Virtual Pins 32 - 127 / 128 - 255 and BLYNK_READ / BLYNK_WRITE

I’d never looked at (or attempted to use) virtual pins 128 - 255 until @Blynk_Coeur brought it up in a related topic. It’s a well-known fact @Blynk_Coeur is a virtual pin addict … he simply can’t get enough of them. :wink:

It is obvious from src/Blynk/BlynkHandlers.h that BLYNK_READ and BLYNK_WRITE don’t support virtual pins 128 – 255. What isn’t obvious is the recommendation to use BLYNK_READ_DEFAULT and BLYNK_WRITE_DEFAULT. @Gunner pointed out this is clearly called out in the Blynk documentation,

image
image

Kudos to the development team for documenting this. I understand (and agree with) the rationale for not wanting to extend the BLYNK_READ and BLYNK_WRITE support, burning additional program memory, given most users don’t need 256 virtual pins (except @Blynk_Coeur, of course).

I’ve never cared for the BLYNK_READ and BLYNK_WRITE macros. They have no type-checking nor range-checking. For example, this code compiles just fine and you’re left troubleshooting why your BLYNK_WRITE and BLYNK_READ macros aren’t being invoked,

#define BUTTON          0
#define VALUE_DISPLAY  33

BLYNK_WRITE(JUNK) {}           // Note: this compiles, yet "JUNK is undefined
BLYNK_READ(JUNK) {}            // Note: this compiles, yet "JUNK is undefined

BLYNK_WRITE(BUTON) { }         // Note: this compiles, yet "BUTTON" is misspelled
BLYNK_READ(VALUE_DISPLY) { }   // Note: this compiles, yet "VALUE_DISPLAY" is misspelled

BLYNK_WRITE(128) { }           // Note: this compiles, yet virtual pin 128 is not supported
BLYNK_READ(128) { }            // Note: this compiles, yet virtual pin 128 is not supported 

Rather than use BLYNK_READ / BLYNK_WRITE for virtual pins 0 - 127 and BLYNK_READ_DEFAULT / BLYNK_WRITE_DEFAULT for virtual pins 128 - 255, I’m going to eliminate my use of BLYNK_READ and BLYNK_WRITE altogether.

I’m compiling out support for BLYNK_READ and BLYNK_WRITE in conjunction with virtual pins 32 - 127 in order to free up the unused program memory,

Here’s the complete test firmware …

Help: If anyone could help me figure out how to include Blynk\BlynkDetectDevice.h without specifying the absolute path I would appreciate it.

#define BLYNK_PRINT Serial

/* 
 * Use this first set of #includes, #defines and #undefs to compile out and free up the
 * program memory used by BLYNK_READ and BLYNK_WRITE with virtual pins 32 - 127
 * 
 * Note:  Expect the following warning,
 * 
 *    #warning "Please include a board-specific header file, instead of Blynk.h (see examples)"
 */
#include <ESP8266WiFi.h>
#define BlynkApi_h
#include <Blynk.h>
#undef BlynkApi_h
#include <Blynk\BlynkDetectDevice.h>
#undef BLYNK_USE_128_VPINS
#include <BlynkSimpleEsp8266.h>

/*
 * Otherwise, use this second set of #includes
 */

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "xxx";
char ssid[] = "xxx";
char pass[] = "xxx";

/*
 * Controller Widget Virtual Pins
 */
#define BUTTON          0
#define SLIDER         32
#define TEXT_INPUT    128
#define NUMERIC_INPUT 254

/*
 * Display Widget Virtual Pins
 */
#define LEVEL_V         1
#define VALUE_DISPLAY  33
#define LABELED_VALUE 129
#define LEVEL_H       255

/*
 * Display Widget Test Values
 */
int level_v       = LEVEL_V;
int value_display = VALUE_DISPLAY;
int labeled_value = LABELED_VALUE;
int level_h       = LEVEL_H;

/*
 * Controller Widget Virtual Pin Functions
 */
void inline blynk_write_button(BlynkParam param) {
   Serial.printf("blynk_write_button: %s\n", param.asString());
}

void inline blynk_write_slider(BlynkParam param) {
   Serial.printf("blynk_write_slider: %s\n", param.asString());
}

void inline blynk_write_text_input(BlynkParam param) {
   Serial.printf("blynk_write_text_input: %s\n", param.asString());
}

void inline blynk_write_numeric_input(BlynkParam param) {
   Serial.printf("blynk_write_numeric_input: %s\n", param.asString());
}

BLYNK_READ_DEFAULT(){
   int pin = request.pin;
   switch(pin) {
      case LEVEL_V:       Blynk.virtualWrite(pin, level_v);       break;
      case VALUE_DISPLAY: Blynk.virtualWrite(pin, value_display); break;
      case LABELED_VALUE: Blynk.virtualWrite(pin, labeled_value); break;
      case LEVEL_H:       Blynk.virtualWrite(pin, level_h);       break;
      default:
         Serial.printf("BLYNK_READ_DEFAULT:  V%d Unsupported\n", pin);
   }
}

BLYNK_WRITE_DEFAULT(){
   int pin = request.pin;
   switch(pin) {
      case BUTTON:        blynk_write_button(param);        break;
      case SLIDER:        blynk_write_slider(param);        break;
      case TEXT_INPUT:    blynk_write_text_input(param);    break;
      case NUMERIC_INPUT: blynk_write_numeric_input(param); break;
      default:
         Serial.printf("BLYNK_WRITE_DEFAULT:  V%d Unsupported\n", pin);
   }
}

void setup(void) {
   Serial.begin(115200);
   Blynk.begin(auth, ssid, pass);
   while (!Blynk.connect());
}

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

Joe

3 Likes

:rofl::rofl::rofl:

1 Like

16-028358 16-028357

  Blynk.virtualWrite(129,digitalRead(16));//RL1 D0
  Blynk.virtualWrite(130,digitalRead(5));//RL2  D1
  Blynk.virtualWrite(131,digitalRead(34));//RL3
  Blynk.virtualWrite(132,digitalRead(35));// RL4
  Blynk.virtualWrite(133,digitalRead(2));//LED wifi built-in
  Blynk.virtualWrite(134,digitalRead(14));//TRIGGER
  Blynk.virtualWrite(135,digitalRead(12));//ECHO
  Blynk.virtualWrite(136,digitalRead(13));//DHT11
  Blynk.virtualWrite(137,digitalRead(15));//Transmiter

The reason why

************************      virtual pin in use  ***************************
    V0 SRV1 LED*
    V1 Lamp1 button 433 Mhz *
    V2 Lamp2 button 433 Mhz  *
    V3 Lamp3 button 433 Mhz  *
    V4 Lamp4 button 433 Mhz  *
    V5 garage button 433 Mhz     *
    V6 outside button 433 Mhz   *
    V7 garden zone1 button 433 Mhz *
    V8 garden zone2 button 433 Mhz   *
    V9 Processor 2 Start Time label*
    V10 All off button    *
    V11 Segmented*
    V12 Fake button*
    V13 IP*
    V14 fuel LED Level    *
    V15 Thermostat Day*
    V16 Thermostat Night*
    V17 Actual hum  DHTP11 label*
    V18 Actual Temp DTH11 label*
    V19 Fake DHTP11 <-------------------------------------
    V20 RX code label*
    V21 Fuel LED*
    V22 running LED / MCU1 LED*
    V23 slider temp eau /label temp désiré*
    V24 RSSI*
    V25 Recnc*
    V26 SRV2 LED*
    V27 WebHook Freebox*
    V28 MCU2 LED*
    V31 DHT LED*
    V32 EXt . Temperature *
    V33 RX LED*       *
    V34 Telnet LED*
    V36 Wifi LED*
    V37 RSI *
    V38 LCD*
    V40 Processor 1 on-line*
    V41 Processor 2 Start Time label*
    V42 Processor 1 Start Time label*
    V43 tempo gauge*
    V44 tempo slider *
    V45 Simulation Mode *
    V50 Lock/Unlok* 1
    V51 Lock/Unlok* 2
    V52 Lock/Unlok LED 1*
    V53 Lock/Unlok LED 2*
    V56 Unlock timer*
    V57 Start timer*
    V57 Wifi LED* 
    V60 Hysteresis*
    V61 DHTP11 correction*
    V62 Input Water T°
    V63 Output Water T° 
    V64 Fuel level*
    V65 Dallas Sensor Led*
    V66 Warm LED*
    V67 Water temp max*
    V68 Water sensor sim
    V69 Fuel Level sim
    V70 HEATING*
    V71 Reset Conso*
    V72 Warning*
    V73 WarmOn*
    V74 default sensor1
    V75 default sensor2
    V76 working time*
    V77 Tota Consol*
    V79 Heating time*
    V80 RELAY*
    V81 RELAY*
    V82 RELAY*
    V83 RELAY*
    V84 RELAY*
    V85 RELAY*
    V86 RELAY*
    V87 RELAY*
    V88 RELAY*
    V89 RELAY*
    V90 RELAY*
    V91 RELAY*
    V92 T° Eau*
    V93 Pente*
    V94 Parallele*
    V95 Fuel Sim*
    V96 temp INT sim*
    V97 Water sim*
    V98 temp EXT sim*
    V99 Ext temp sim
    V100 WebHook openweather*
    V101 Prog1*
    V103 Prog2*
    V105 Prog3*
    V107 Prog4*
    V109 Prog5*
    V111 Prog6*
    V113 Prog7*
      */
2 Likes

Would someone please help me to compile this …

#include <ESP8266WiFi.h>
#include <Blynk\BlynkDetectDevice.h>
#undef BLYNK_USE_128_VPINS
#include <BlynkSimpleEsp8266.h>

void setup(void) {}
void loop(void) {}

The compiler can’t find Blynk\BlynkDetectDevice.h. I don’t know if I have a path set wrong in the IDE or what.

Not sure what you are making here… but just use #include <BlynkDetectDevice.h> (without the Blynk\) as that file is part of the normal library and is actually in the src subfolder.

Does that work for you? I get,

image

I’m trying to compile BLYNK_READ and BLYNK_WRITE out of the code for virtual pins V32 - V127. It works fine, however, I need to fully qualify the path to BlynkDetectDevice.h.

I didn’t try, I just thought the addition or the Blynk\ was odd. Just search for the file location in your libraries and use that path (EDIT - I see you have already done this :slight_smile: ).

I do not profess to understand the makings of libraries, but it seems some files are meant to be called from others, not used directly. This seems to be one of those cases.

I am still unsure of the reason behind all this… the use of the BLYNK_WRITE(), etc. functions is fairly clear and since nothing but vPins are supposed to be used in the brackets anyhow, why worry if other extraneous values are compiled or not.

It’s not that odd.

#include <BlynkSimpleEsp8266.h>

in turn includes,

#include <BlynkApiArduino.h>
#include <Blynk/BlynkProtocol.h>
#include <Adapters/BlynkArduinoClient.h>
#include <ESP8266WiFi.h>

The difference is BlynkSimpleEsp8266.h is in a different directory than my sketch. I’ve tried relative paths,

#include "..\Blynk\BlynkDetectDevice.h"

I can’t get anything to work, except …

Again, if I fully qualify the path, it works fine …

#include <ESP8266WiFi.h>
#include <C:\Users\Joe\Documents\Arduino\libraries\Blynk\src\Blynk\BlynkDetectDevice.h>
#undef BLYNK_USE_128_VPINS
#include <BlynkSimpleEsp8266.h>

void setup(void) {}
void loop(void) {}

I shouldn’t have to do that.

You sure you want to know? :wink:

In order to remove BLYNK_READ and BLYNK_WRITE for virtual pins 32 - 127 from the code, I need to,

#undef BLYNK_USE_128_VPINS

BLYNK_USE_128_VPINS is defined in Blynk/BlynkDetectDevice.h. As you can see, Blynk/BlynkDetectDevice.h is nested five levels of #include deep,

#include <BlynkSimpleEsp8266.h>
   #include <BlynkApiArduino.h>
      #include <Blynk/BlynkApi.h>
         #include <Blynk/BlynkConfig.h>
            #include <Blynk/BlynkDetectDevice.h>

I need to undefine BLYNK_USE_128_VPINS after Blynk/BlynkDetectDevice.h is included, but before

Blynk/BlynkHandlers.h

That’s why I’ve pulled Blynk/BlynkDetectDevice.h out, undefined BLYNK_USE_128_VPINS and then proceeded with my normal includes.

Everything works fine. BLYNK_READ and BLYNK_WRITE for virtual pins 32 - 127 has been successfully removed from my binary. I’m just trying to make the path to Blynk/BlynkDetectDevice.h more portable.

The BLYNK_READ and BLYNK_WRITE macros are simply poor programming constructs.

More importantly, as you pointed out last night, the BLYNK_READ and BLYNK_WRITE macros don’t support all of the virtual pins. Why would I want to use one programming construct for virtual pin 127 and a different programming construct (BLYNK_READ_DEFAULT and BLYNK_WRITE_DEFAULT) for virtual pin 128? If I want to reassign a widget to a different virtual pin, I may well have to write different code, rather than simply changing a constant.

As you pointed out last night, BLYNK_READ and BLYNK_WRITE waste program memory corresponding to unused virtual pins. I’m getting rid of BLYNK_READ and BLYNK_WRITE (at least corresponding to virtual pins 32 - 127 … they’re not defined for virtual pins 128 - 255) and I’m using BLYNK_READ_DEFAULT and BLYNK_WRITE_DEFAULT exclusively … one programming construct regardless of the virtual pin I’m using.

1 Like

I wouldn’t know… am not the developer… but that is how Blynk, the Examples and the Docs are written and work, at least for the majority. I just think the term reinventing the wheel is applicable :stuck_out_tongue_winking_eye: but then that is the joy and benefit of an Open Source Library, so keep at 'er. :+1:

Anyhow, I shouldn’t have chipped in without fully understanding your topics purpose :blush: So I will just continue to watch and read and perhaps even learn (it happens) :smiley:

1 Like

I think I figured it out …

With this syntax, the compiler thinks Blynk\BlynkDetectDevice.h is associated with the ESP8266WiFi library. It’s looking for Blynk\BlynkDetectDevice.h in the wrong directory,

#include <ESP8266WiFi.h>
#include <Blynk\BlynkDetectDevice.h>
#undef BLYNK_USE_128_VPINS
#include <BlynkSimpleEsp8266.h>

void setup(void) {}
void loop(void) {}

If I include Blynk.h just prior to Blynk\BlynkDetectDevice.h, the compiler knows Blynk\BlynkDetectDevice.h is associated with the Blynk library. The compiler is able to find the file,

#include <ESP8266WiFi.h>
#include <Blynk.h>
#include <Blynk\BlynkDetectDevice.h>
#undef BLYNK_USE_128_VPINS
#include <BlynkSimpleEsp8266.h>

void setup(void) {}
void loop(void) {}

Unfortunately, Blynk.h wasn’t intended to be used. It includes a warning,

Even more unfortunate, Blynk.h #includes Blynk/BlynkApi.h which ultimately #includes Blynk/BlynkDetectDevice.h and Blynk/BlynkHandlers.h which I’m trying to avoid at this point.

This is the only solution,

#include <ESP8266WiFi.h>
#define BlynkApi_h
#include <Blynk.h>
#undef BlynkApi_h
#include <Blynk\BlynkDetectDevice.h>
#undef BLYNK_USE_128_VPINS
#include <BlynkSimpleEsp8266.h>

void setup(void) {}
void loop(void) {}

I may just have to live with the program memory wasted on BLYNK_READ and BLYNK_WRITE. The #includes simply become the tried and true,

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

void setup(void) {}
void loop(void) {}
1 Like

It compiled in my case:
Sketch uses 268480 bytes (53%) of program storage space. Maximum is 499696 bytes.
Global variables use 27600 bytes (33%) of dynamic memory, leaving 54320 bytes for local variables. Maximum is 81920 bytes.

ESP8266 with NO SPIFFS

Hi @Emilio,

I didn’t mean to imply that Blynk.h doesn’t compile or not work. It works fine. I just don’t think the developers would’ve put the “instead of” warning,

#warning "Please include a board-specific header file, instead of Blynk.h (see examples)"

in it had they intended us to use it.

I wish the developers would just gut Blynk.h. If my understanding is correct, Blynk.h is needed in order to directly #include files such as Blynk\BlynkDetectDevice.h. It serves to identify the Blynk library.

Better yet, I wish the developers would restructure the nested #includes and preprocessor directives such that we could more easily,

#undef BLYNK_USE_128_VPINS

from a sketch without having to jump through so many hoops.

On a related note … you’ll notice, with #undef BLYNK_USE_128_VPINS,

  #define V32 32
  #define V33 33
  ...
  #define V127 127

are no longer defined. Of course,

  #define V128 128
  #define V129 129
  ...
  #define V255 255

were never defined. I just use integers (0, 1, … 255) to reference the virtual pin numbers,

/*
 * Controller Widget Virtual Pins
 */
#define BUTTON          0
#define SLIDER         32
#define TEXT_INPUT    128
#define NUMERIC_INPUT 254

Thank you for taking the time to test this.

Joe

1 Like