Using Blynk widgets in custom classes

Hello Blynks,

I am a C++ and Blynk newbie, so my question might be answered before, but I have not found anything. I am not sure I can even explain my problem in the right C++ terms :wink:

I am using a Particle Photon board.

I would like to call Blynk functions from different classes defined in different libraries.

Ex. Parse the Blynk object to another object, that takes care of my DS18B20 sensors, so this object can update my Blynk App. Or implement all my Blynk stuff in one library, and expose the Blynk objects.

I can make a pointer variable to the main Blynk object defined in “BlynkSimpleParticle_h”

// myBlynkTest.h
#include "blynk/BlynkParticle.h"

class BlynkPrtTestClass {
    
    public:
        BlynkParticle *BlynkPrt;
        
        BlynkPrtTestClass(BlynkParticle *_BlynkPrt);
        void testBlynk();
        
};
// end - myBlynkTest.h


// myBlynkTest.cpp
#include " myBlynkTest.h "

BlynkPrtTestClass::BlynkPrtTestClass(BlynkParticle *_BlynkPrt) {
    BlynkPrt = _BlynkPrt;
}

void BlynkPrtTestClass::testBlynk() {
    BlynkPrt->virtualWrite(V8,millis());
}
// end - myBlynkTest.cpp

// test.ino
#include "myBlynkTest.h"
#include "blynk/blynk.h"

char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

BlynkPrtTestClass ObjWithBlynk(&Blynk);

void setup() {
  Blynk.begin(auth);

  while (Blynk.connect() == false) {
  }

}

uint32_t lastBlynkMillis=0;

void loop() {
  Blynk.run();
  
  if(millis()-lastBlynkMillis>2000) {
      lastBlynkMillis=millis();
      ObjWithBlynk.testBlynk();
  }
}
// end - test.ino

But I would like to do the same for the widget objects. For example define a pointer-variable to a led, terminal or LCD object in a “custom” class declared in separate .h file. For example having a DS18B20 class with a pointer-variable pointing at a WidgetTerminal object.

In the WidgetXXX.h files, the Blynk object is expected to be “known”, but that happens in “BlynkSimpleParticle_h”, which I can not include in a library file be course “Blynk” is already defined ?

I have “solved” the problem by making my own versions of the WidgetXXX.h files and use a BlynkParticle pointer as argument for the constructor event – and move the declaration of:
static BlynkTransportParticle _blynkTransport;
BlynkParticle Blynk(_blynkTransport);

to the .ino file, so I don’t use “Blynk.h” & “BlynkSimpleParticle.h”.

This seems to work, but now I am not using the standard Blynk libraries and will have to update manually when new Blynk libraries are deployed !

Is this really stupid and is there a smarter solution ?

Br Michael

Only @vshymanskyy could help you here :). I’m not very familiar with C++.

What exactly are you trying to do? There might be a different solution but it’s hard to know since your post is too generic (or maybe my English is bad and I didn’t get it)

Thx for answering.

Maybe my biggest problem is how to explain what I am aiming at :wink:

I have a quit large Particle Photon application. The code is structured so I have different classes (libraries), that takes care of different stuff. One reads temperature sensors, calculates average values, checks levels for alarms etc. Another class switches 16 relays in defined patterns, another checks a number of water levels sensor, another reads lumen,humidity and bio-metric pressure. Another reads PH level and controls a CO/2 solenoid. Another runs a scheduler so different things happen at different times. And so on…

But I ended up with very messy code bc I could not put the code for Blynk interfaces (VirtualWrite, widgetTerminal.print etc) in each of these libraries (using the “standard” Particle implementation). All Blynk code had to be in the .ino file. And in the Particle world, you can only have one .ino files, all other code must be placed in .h and .cpp files.

Basically what I want is to parse a pointer to Blynk and widgets objects to my own classes, so I can isolate all functionality concerning for instance water level reading – including getting and sending data to the Blynk app/cloud (Iphone).

I have overcome that challenge, but by slightly changing the “standard” Blynk library (only the Widgetxxx.h files). But now I have a maintenance issue, and a feeling, that I could have accomplished the same without customizing the Blynk libraries.

Having my lack of c++ experience in mind, I believe this should be possible for most general libraries – and certainly Blynk. And it is possible for all the other libraries I use. The Blynk libraries seems to be very well thought and designed, so I guess the problem is at my end :wink:

Does this better explain my problem?

Yes, it’s easier to understand now.
Why don’t you implement functions on your code instead of trying to make new libraries? Something like this:

void ReadTemp() //Read temperature from sensor and activate relay
{
  sensors.requestTemperatures();
  //Blynk.virtualWrite(0, sensors.getTempCByIndex(0)); 
  lcd.print(0, 0, "Temp:");
  lcd.print(5, 0, sensors.getTempCByIndex(0));
  lcd.print(11, 0,"°C"); 

  if(tempMeasured>maxTemp&&userSet!=1)
  {
    digitalWrite(relay, LOW);
    lcd.print(0, 1, "DESLIGADO");
  }
  if(tempMeasured<65&&userSet!=0)
  {
    digitalWrite(relay, HIGH);
    lcd.print(0, 1, "LIGADO   ");
  }
  if(tempMeasured>=90)
  {
    digitalWrite(relay, LOW);
    lcd.print(0, 1, "DESLIGADO");
   }
}

In this case I used timer.setInterval(1000L, ReadTemp); to call up ReadTemp() every second so it wont flood and cause me to disconnect but you use anything you want to trigger them.

I don’t know exactly what you are doing but maybe you could try making a different function for each sensor like ReadTemp() and place the code to take measure, calculate average values and other stuff and them the Blynk interface (VirtualWrite), Relay() and place the code to make them act and so on.
I would also place inside every function the code for Blynk interfaces like I did before so everytime you call the function it will update status or send info to Blynk server (always taking care so you won’t get disconnected for flooding).

If you are working on something critical and can’t use timers to make your hardware act you can also keep the sensor readings inside Void loop() and place some if() to call your functions every time the condition is met.

1 Like

I would suggest that you create all your classes with needed functionality, and then just bind them with widgets and virtual pins to the Blynk library.
I mean, do not refer directly to blynk from your business logic classes.

AndreSepulveda
This is actually what I would like to do, just not in my main .INO file. In a large project with many and different sensors, relays etc. and interfaces to Blynk, Google, ThingSpeak, LCD’s a.m., my single .ino file will be gigantic and I will need to place a lot of my business logic there. Since I only have this problem with Blynk, I hope there is a way out :wink:

vhymanskyy
I agree. I just don’t know how to do this smart - what do you mean by “bind" them”?

At the moment I will try using callback functions in my classes. This way I have business logic and “distribution/GUI” logic separated.

But I would like to be able to place the Blynk code somewhere else than in the .ino file.

Can you give me an example or some pointers to, in a Particle+Blynk project, place “Blynk widget code” (ex. WidgetTerminal.print) anywhere else but in the .ino project file.

Yes you should be able to add another file in Arduino IDE and put all Blynk functionality in it.
For example: https://github.com/sparkfun/Blynk_Board_ESP8266/tree/master/Firmware/BlynkBoard_Core_Firmware

It’s better to put ALL blynk-related stuff in 1 file, otherwise it may break things.

Yes I know and thanks for answering.

That is exactly what I am trying to accomplish :wink:

But I am not not working on an Arduino platform.

I 'm using the Photons and Bluz boards and the Particle Web Build IDE.

I have no problems in “Arduino world”, but in “Particle world”, I have a problem due to the way Blynk is implemented and the way the compiler file structure is set up.

It is very easy to fix, but if I do it, I kind of cut the link to Blynk documentation, new versions etc. And since my solution will be shared by other developers, I would like to use standard available libraries for anything except my own application design and business logic.

Could you message me directly with the proposed changes?

Done :relaxed:

~Michael