Having More than one file besides main.cpp

Hello, being new I suspect I am not getting the correct search terms so I cannot find an answer. Here is what I want to do. Instead of having one big blob in main.cpp I wish to learn how to break it down into multiple cpp files but I am having problems with keywords not declared in this scope. Some I can fix but this one I cannot.

When i create an instance of a library, for example “BlynkTimer timer;” and then I use “timer.setInterval(1000L, myTimerEvent);” in my setup.

Now, I create a new file called ntp.cpp where I query a time server. And in that file I create another Blynk timer event called “timer.setInterval(3540000L, ntpEvent);”. When I compile I keep getting the following error:

Compiling .pio\build\esp-wrover-kit\src\ntp.cpp.o
src\ntp.cpp: In function 'void initNTP()':
src\ntp.cpp:28:3: error: 'timer' was not declared in this scope
   timer.setInterval(3540000L, ntpEvent); // call every 59m until the correct hour
   ^
*** [.pio\build\esp-wrover-kit\src\ntp.cpp.o] Error 1

I have tried everything. What I expect to work is to reference this in ntp.cpp as

extern BlynkTimer timer; 

But that does not work. How do I do this?

This is correct for the declaration of the variabation. Where are you defining it, with the corresponding BlynkTimer timer; line of code? The variable won’t physically exist until you define it.

Thank you for your help maxgerhardt. Hopefully it is clear when I say I have everything working in main.cpp.

Then in ntp.cpp I am inching along so I just created the following:

/*
 *  Get time from time server
 *  
 */
#include <arduino.h>
#include <BlynkSimpleEsp32.h>

extern BlynkTimer timer;  // I invoke this library in main.cpp and I expect the "extern" command to use it.

void ntpEvent(){}              // haven't populated this yet.

void initNTP()
{
  timer.setInterval(3540000L, ntpEvent); // call every 59m until the correct hour
}

Then in ntp.h:

/*
 *  Get time from time server
 *  
 */
void initNTP(void);
void ntpEvent(void);

And when I compile I get this error:

Linking .pio\build\esp-wrover-kit\firmware.elf
.pio\build\esp-wrover-kit\src\ntp.cpp.o:(.bss.Blynk+0x0): multiple definition of `Blynk'
.pio\build\esp-wrover-kit\src\main.cpp.o:(.bss.Blynk+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\esp-wrover-kit\firmware.elf] Error 1

I have tried all sorts of combinations and either get this or some other error I cannot fix.

You’re only allowed to include this header in one file because the authors have written it in such a way that it creates an instances of the variable in every file it is included.

So if you include it in main.cpp and ntp.cpp you will get that multiple definition of 'Blynk' error.

The BlynkSimpleEsp32.h is not meant for inclusion from multiple cpp files.

The fix depends on what exactly you want to do – You can write your own version of the header file that doesn’t instantiate the variables so that this is possible in only one cpp file.

Though you don’t seem to need access to all the internal definitions of that file…

In ntp.cpp you could try and replace

With

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

as a workaround.

Why would Blynk write it this way? I feel like it is preventing people from developing good programming habits. So I tried what you indicated and get a whack of errors shown below.

Does Blynk have a header file that will allow me to do this?

Building in release mode
Compiling .pio\build\esp-wrover-kit\src\ntp.cpp.o
In file included from .pio\libdeps\esp-wrover-kit\Blynk\src/WidgetLED.h:13:0,
                 from .pio\libdeps\esp-wrover-kit\Blynk\src/BlynkWidgets.h:10,
                 from src\ntp.cpp:9:
.pio\libdeps\esp-wrover-kit\Blynk\src/Blynk/BlynkWidgetBase.h: In member function 'void BlynkWidgetBase::setLabel(Args ...)':        
.pio\libdeps\esp-wrover-kit\Blynk\src/Blynk/BlynkWidgetBase.h:27:9: error: 'Blynk' was not declared in this scope
         Blynk.setProperty(mPin, "label", args...);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/Blynk/BlynkWidgetBase.h: In member function 'void BlynkWidgetBase::setColor(Args ...)':        
.pio\libdeps\esp-wrover-kit\Blynk\src/Blynk/BlynkWidgetBase.h:32:9: error: 'Blynk' was not declared in this scope
         Blynk.setProperty(mPin, "color", args...);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/Blynk/BlynkWidgetBase.h: In member function 'void BlynkWidgetBase::setMin(Args ...)':
.pio\libdeps\esp-wrover-kit\Blynk\src/Blynk/BlynkWidgetBase.h:37:9: error: 'Blynk' was not declared in this scope
         Blynk.setProperty(mPin, "min", args...);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/Blynk/BlynkWidgetBase.h: In member function 'void BlynkWidgetBase::setMax(Args ...)':
.pio\libdeps\esp-wrover-kit\Blynk\src/Blynk/BlynkWidgetBase.h:42:9: error: 'Blynk' was not declared in this scope
         Blynk.setProperty(mPin, "max", args...);
         ^
In file included from .pio\libdeps\esp-wrover-kit\Blynk\src/BlynkWidgets.h:10:0,
                 from src\ntp.cpp:9:
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetLED.h: In member function 'void WidgetLED::setValue(uint8_t)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetLED.h:30:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, value);
         ^
In file included from .pio\libdeps\esp-wrover-kit\Blynk\src/BlynkWidgets.h:11:0,
                 from src\ntp.cpp:9:
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetLCD.h: In member function 'void WidgetLCD::clear()':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetLCD.h:22:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, "clr");
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetLCD.h: In member function 'void WidgetLCD::print(int, int, const T&)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetLCD.h:33:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, cmd);
         ^
In file included from .pio\libdeps\esp-wrover-kit\Blynk\src/BlynkWidgets.h:12:0,
                 from src\ntp.cpp:9:
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTerminal.h: In member function 'virtual void WidgetTerminal::flush()':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTerminal.h:52:13: error: 'Blynk' was not declared in this scope
             Blynk.virtualWriteBinary(mPin, mOutBuf, mOutQty);
             ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTerminal.h: In member function 'void WidgetTerminal::clear()':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTerminal.h:59:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, "clr");
         ^
In file included from .pio\libdeps\esp-wrover-kit\Blynk\src/BlynkWidgets.h:13:0,
                 from src\ntp.cpp:9:
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h: In member function 'void WidgetBridge::setAuthToken(const char*)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h:30:9: error: 'Blynk' was not declared in this scope
         Blynk.sendCmd(BLYNK_CMD_BRIDGE, 0, cmd.getBuffer(), cmd.getLength()-1);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h: In member function 'void WidgetBridge::digitalWrite(const T&, int)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h:41:9: error: 'Blynk' was not declared in this scope
         Blynk.sendCmd(BLYNK_CMD_BRIDGE, 0, cmd.getBuffer(), cmd.getLength()-1);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h: In member function 'void WidgetBridge::analogWrite(const T&, int)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h:52:9: error: 'Blynk' was not declared in this scope
         Blynk.sendCmd(BLYNK_CMD_BRIDGE, 0, cmd.getBuffer(), cmd.getLength()-1);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h: In member function 'void WidgetBridge::virtualWrite(int, Args ...)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h:63:9: error: 'Blynk' was not declared in this scope
         Blynk.sendCmd(BLYNK_CMD_BRIDGE, 0, cmd.getBuffer(), cmd.getLength()-1);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h: In member function 'void WidgetBridge::virtualWriteBinary(int, const void*, size_t)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetBridge.h:72:9: error: 'Blynk' was not declared in this scope
         Blynk.sendCmd(BLYNK_CMD_BRIDGE, 0, cmd.getBuffer(), cmd.getLength(), buff, len);
         ^
In file included from .pio\libdeps\esp-wrover-kit\Blynk\src/BlynkWidgets.h:15:0,
                 from src\ntp.cpp:9:
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h: In member function 'void WidgetTable::clear()':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h:44:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, "clr");
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h: In member function 'void WidgetTable::addRow(int, const T1&, const T2&)':       
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h:49:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, "add", index, name, value);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h: In member function 'void WidgetTable::updateRow(int, const T1&, const T2&)':    
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h:54:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, "update", index, name, value);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h: In member function 'void WidgetTable::pickRow(int)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h:58:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, "pick", index);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h: In member function 'void WidgetTable::selectRow(int)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h:62:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, "select", index);
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h: In member function 'void WidgetTable::deselectRow(int)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetTable.h:66:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, "deselect", index);
         ^
In file included from .pio\libdeps\esp-wrover-kit\Blynk\src/BlynkWidgets.h:17:0,
                 from src\ntp.cpp:9:
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetMap.h: In member function 'void WidgetMap::clear()':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetMap.h:22:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, "clr");
         ^
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetMap.h: In member function 'void WidgetMap::location(const T1&, const T2&, const T3&, const T4&)':
.pio\libdeps\esp-wrover-kit\Blynk\src/WidgetMap.h:27:9: error: 'Blynk' was not declared in this scope
         Blynk.virtualWrite(mPin, index, lat, lon, value);
         ^
*** [.pio\build\esp-wrover-kit\src\ntp.cpp.o] Error 1
==================================================== [FAILED] Took 8.15 seconds ====================================================
The terminal process "C:\Users\Steve\.platformio\penv\Scripts\pio.exe 'run'" terminated with exit code: 1.

Terminal will be reused by tasks, press any key to close it.

Ah my bad, the following BlynkWidgets.h includes code as well that directly references the Blink variable but that won’t work. You can try to not write

#include <BlynkWidgets.h>

and write instead

class BlynkWifi;
//or: class BlynkWifi : public BlynkProtocol<BlynkArduinoClient>;
extern BlynkWifi Blynk;

But if that doesn’t work , then the only way to solve this is to write a modified header file.

Probably because they only expect this to go into a single file as it would be for most Arduino IDE usecases. Or, I’m misunderstanding the library and you don’t have to actually include this header in every file but some lighter version of it?

If there’s still errors can you please post the full code (including platformio.ini and main.cpp etc)

I guess I will just lump it all into one file.

Thank you maxgerhardt.