Naming the steps of a Step Widget?

As it stands now, my dosing pump project works perfectly, and the functionality is just right “all” thanks to Blynk! However, if this project is copied by someone with even less code/circuit skills than myself, I would want them to have an easier to understand project in the end.

THIS youtube video depicts the functionality of my project while also showing my app being interacted with. I refer specifically to the first Step widget titled PUMP#. This widget allows me to select from 1 of 8 pumps. I as the creator will know what I put on pump 1, 2, 3 etc in terms of nutrient solutions, but other users, especially those that use this as a bartender would likely be consuming the cocktails made and likely forget which liquor is assigned to pump 1, 2, 3 etc. All of that said, and as the title states, I would like expanded functionality of the Step widget to include a variable name display, or even a new display app that can piggy back onto existing widgets to display the names in the array. As of this morning, I updated my sketch to print these names out onto the terminal monitor when the code is being executed on a respective pin and array position, but this is an ‘after the fact’ result. I seek the ability to step from name to name instead of number to number.

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

SimpleTimer timer;
WidgetTerminal terminal(V3);

int pumpPin[8] = { 2, 3, 4, 5, 6, 7, 8, 9 };         //Digital pins used
uint32_t multiplier[8] =  { 858, 827, 872, 865, 887, 895, 913, 843 }; //ms per ml
uint32_t startPump = 0;
uint32_t runCount;
float DOSEml;           //V1 Step Widget (0.25 per step, send step/NO, loop values ON)
int button = 0;         //V2 Button Widget set to Switch
bool pumpRunning = false;
int x;
const char *y[8] = { "armorSi", "floraBlend", "caliMagic", "koolBloom",
                   "floraGro", "floraMicro", "floraBloom", "phDown" };

BLYNK_WRITE(V0) {                 // Choose Pump
  x = param.asInt() - 1;
}
BLYNK_WRITE(V1) {                 // Adjust Dosage
  DOSEml = param.asFloat();
}
BLYNK_WRITE(V2) {                 // Activate Chosen Pump
  button = param.asInt();
}

void checkPump()
{
  if (button == 1 && pumpRunning == false)
  {
    Blynk.virtualWrite(V0, 0);
    Blynk.virtualWrite(V1, 0);
    Blynk.virtualWrite(V2, 0);
    pumpRunning = true;
    digitalWrite(pumpPin[x], HIGH);
    startPump = millis();
    runCount = DOSEml * multiplier[x];
    terminal.print("Dosing in: ");
    terminal.print(DOSEml);
    terminal.print(" milliliters of ");
    terminal.println(y[x]);
    terminal.flush();
  }

  if (millis() - startPump > runCount)
  {
    digitalWrite(pumpPin[x], LOW);
    pumpRunning = false;
    button = 0;
  }
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth);
  while (Blynk.connect() == false) {}
  timer.setInterval(100L, checkPump);
  for (int p = 0; p <= 7; p++)
  {
    pinMode(pumpPin[p], OUTPUT);
  }
  Blynk.virtualWrite(V0, 0);
  Blynk.virtualWrite(V1, 0);
  Blynk.virtualWrite(V2, 0);
}

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

Hi !
Nice application of Blynk ! :slight_smile:

Could you use the Menu-widget instead? This will give a number and you can assign a lable to it.

/BR

1 Like

Hey @myggle, love your project, I’ve been following your thread and development.

I think I understand what you’re asking. It’s really quite simple to add.

These are the names you want to assign?

const char *y[8] = { "armorSi", "floraBlend", "caliMagic", "koolBloom",
                   "floraGro", "floraMicro", "floraBloom", "phDown" };

If so, then you have already done the hard part setting up the array! Howerver I would declare it slightly differently like below. You dont have to so this but throwing it out there because working with char arrays really sucks.

String y[9] = {"armorSi", "floraBlend", "caliMagic", "koolBloom", "floraGro", "floraMicro", "floraBloom", "phDown" }; // always use +1 on the number of spaces in the array for the index

Then you can just modify the Pump selection widget function

BLYNK_WRITE(V0) {                 // Choose Pump
  x = param.asInt() - 1;
  Blynk.virtualWrite(V4,String(y[x])); // pick the name from the array and send it to a value widget on pin V4
}

Let me know if I got this totally wrong and didn’t understand your questions hah :smiley:

Edit, oh and please change the var x to something like pumpSelected and y to pumpName :smile:

2 Likes

@fxfever - Thank you, this is exactly what I was looking for. I feel like an idiot for not first ruling out existing widgets! I simply dropped the Step widget on V0 and added in the Menu on VO with all my names I wanted in the fields and didn’t change the code any as the variable x is already set to be read minus one.

x = param.asInt() - 1;

@Jamin - You’re the second guy within a 12 hour span to remind me to use more meaningful names than “x” and “y”. I will definitely adjust that soon and also adjust the sketch on my project page.

I don’t understand the reason to change the array of pointers to an array of Strings? As it is now, the code executes flawlessly and prints the statements I want printed to the terminal monitor. FYI, I have not yet studied about using String class so I am hesitant in changing something if I don’t know why to something I don’t know about. Still too new to coding I guess.

@Myggle your amount of arrays is growing :stuck_out_tongue:

I’ll just leave this here for you to do with as you please. This refers to using structs.
For more info read here: http://playground.arduino.cc/Code/Struct

Basically a struct “enables the programmer to create a variable that structures a selected set of data.”

You could define your pump as such (or similar)
saying that every one pump has a string as name,
a string for description, an int for multiplier and an int for a hardware pin.

You can fiddle with the exact datatypes as you see fit (uint32_t etc)

Here we define how the pump “looks like” in terms of what data it holds. This is basically a “sketch” of how a pump is defined

struct NutrientPump {
    string name;
    string description;
    int multiplier;
    int hwPin;
} ;

Next we can initiate a single variable of type NutrientPump like this

// from top to bottom/left to right
NutrientPump myPump = { "PumpNameAsString", "PumpDescriptionAsString", 875, 2 };

or similarly like this

NutrientPump myPump;
myPump.name = "PumpNameAsString";
myPump.description = "PumpDescriptionAsString";
myPump.multiplier = 875;
myPump.hwPin = 2;

So as you can see this acts similar to an array but with the benefit of being able to mix different datatypes.
As with “int myArray[5]” you are tied to only use integers. Struct allows you to mix.

You can also define an array of 8 pumps this way. This will give you an array of 8 NutrientPumps
which can be accessed by indexing as regular arrays.
And when you get one, you can access its data.

NutrientPump myPumps[arrSize] = {
	    { "Test1", "Description1234", 765, 2 },
	    { "Test2", "Description12", 777, 3 },
	    { "Test3", "Description314", 875, 4 },
	    { "Test4", "Description523", 745, 5 },
	    { "Test6", "Description1234", 765, 6 },
	    { "Test7", "Description12", 777, 7 },
	    { "Test8", "Description314", 875, 8 },
	    { "Test9", "Description523", 745, 9 },
	    
	}; 

Like this for instance. It will print all the content of “myPumps” which is of type NutrientPump

for (int i = 0; i < 8; i++)
{
    terminal.println(myPumps[i].name);
    terminal.println(myPumps[i].description);
    terminal.println(myPumps[i].multiplier);
    terminal.println(myPumps[i].hwPin);
    terminal.println();
}
terminal.flush();

[details=Prints this]Test1
Description1234
765
2

Test2
Description12
777
3

Test3
Description314
875
4

Test4
Description523
745
5

Test6
Description1234
765
6

Test7
Description12
777
7

Test8
Description314
875
8

Test9
Description523
745
9[/details]

3 Likes

Hi Fettkeewl, thanks again for sharing your knowledge. Correct me if I’m wrong, but wouldn’t structs be more useful in a situation where recipes were used? Don’t get me wrong, I am 100% heading that way, but as you noted in another thread, structs are out of my league and it will take some time for me to expand my knowledge to that level. Would structs be useful in this project in it’s current state of Dial-a-Dose?

No probs :stuck_out_tongue: Well… to be honest I can’t tell when its preferable to use one over the other, I can just say that a struct for me, is a more elegant way of doing your code because at some point
arrays upon arrays upon arrays will get just a bit to much to read through.

Looking at it from a readable/comprehendable point of view I personally find structs easier to follow in lengthy codes.

struct NutrientPump {
    string name;
    string description;
    int multiplier;
    int hwPin;
} ;

as opposed to

string names[8] 
string description[8]
... etc

I don’t think they are out of your league, not any more at least :stuck_out_tongue: evidently you comprehend arrays much better now that you comfortably add your own and use them in functions for printing text etc.

For simplicitys sake just look at it as more organized coding for your pumps. Grouping all sub-parts sutch as hardware pins used, multipliers and the likes into a group/datatype called “NutrientPump”

In any case, changing this will only extend your knowledge about programming, it wont affect your code in any better or worse way. Whether or not you choose to do so is up to you :slight_smile:

edit: I’m trying to find a better way to explain but it’s hard… heres a go at it

When you buy a car
Arrays: I bought 4 car doors, i bought 1 engine, i bought 4 tires. etc etc
then i superglued them to a car.

Struct: I bought 1 car, the car has 4 doors, 1 engine, 4 tires, 1 exhaust, its color is blue
I got a fully operational car from the get go!

1 Like

So glad you share you’re deep knowledge of C/C++ with us @Fettkeewl ! I’ve been trying to work out how to use Structs for quite a while and you really did just make it super easy to understand! :smiley:

2 Likes

Struct: I woke up and checked Blynk forum, @Fettkeewl delves into arrays and structures, all the colours turned purple!, my head imploded!

But seriously, Thank you @Fettkeewl there is “structure” here, I sense it… but I think I will need to revisit this with a clearer head.

2 Likes

Though I still know very little of structs, I can somewhat see how the data is kept in a cleaner more organized manner which of course equates to easier accessibility, but there’s still so much confusion that I honestly don’t even know how to express it. As I stated in previous threads that these dosing pumps are part of a larger project I’ve been trying to build for years now, one of the 2 remaining facets I’m yet to tackle will undoubtedly require structs, and my confusion of the matter frustrates me ATM. As the larger project is a hydroponics controller, I will acquire or build roughly 13 valves to control the flow of water and nutrients. This will involve each of the 8 pumps, 3 water pumps currently connected to relays and 13 valves. I imagine my current path will lead me to a ball of knotted yarn as it relates to my sketch.:laughing: I will do my diligence and read and reread and rereread till I comprehend them. I do find it somewhat easier to learn a new coding skill when it directly relates to my project. Just gotta get over this hump!

While I appreciate the feedback I’ll be honest and say my C/C++ knowledge is merely shallow :sweat_smile:
I’ve taken some C# oriented programming classes and some Java but I actually graduated as a bachelor of science in the field of energy :stuck_out_tongue: so this is mostly a hobby. Don’t expect miracles :smiley: I share what I understand :wink:
Albeit with crackly explanations.

No probs! Try some duct tape around your head next time while reading and it just might hold :wink:
And feel free to ask any questions, either I or someone else will try to answer!

@myggle you are in for a ride I tell you. Best to learn Structs then :stuck_out_tongue:
I think it would be easier in the long run!
Start a new sketch, copy my code and fiddle around until you get a sense of it.

3 Likes