Working on a project with Arduino MKR WIFI 1010. I’m using the example from Blynk Edgent_MKR1010
Attempting to implement wifi provisioning but attempts to verify yield a error of:
"Compilation error: conflicting declaration ‘WiFiSSLClient _blynkWifiClient’’
Removing underlines results in “Compilation error: redefinition of ‘BlynkWifiCommon Bynk’” instead
Using libraries:
WiFiNINA v1.8.13
ArduinoOTA v1.0.9
Blynk v1.2.0
Flashstorage v1.00
ArduinoHttpClient v0.4.0
This is the code under “BlynkEdgent.h”
extern "C" {
void app_loop();
void restartMCU();
}
#include "Settings.h"
#include <SPI.h>
#include <WiFiNINA.h>
#define BLYNK_SEND_ATOMIC
#include <Blynk.h>
#include <Adapters/BlynkWiFiCommon.h>
WiFiSSLClient _blynkWifiClient;
BlynkArduinoClient _blynkTransport(_blynkWifiClient);
BlynkWifiCommon Blynk(_blynkTransport);
#include <BlynkWidgets.h>
#ifndef BLYNK_NEW_LIBRARY
#error "Old version of Blynk library is in use. Please replace it with the new one."
#endif
#if !defined(BLYNK_TEMPLATE_ID) || !defined(BLYNK_DEVICE_NAME)
#error "Please specify your BLYNK_TEMPLATE_ID and BLYNK_DEVICE_NAME"
#endif
#include "BlynkState.h"
#include "ConfigStore.h"
#include "ResetButton.h"
#include "ConfigMode.h"
#include "Indicator.h"
#include "OTA.h"
#include "Console.h"
inline
void BlynkState::set(State m) {
if (state != m && m < MODE_MAX_VALUE) {
DEBUG_PRINT(String(StateStr[state]) + " => " + StateStr[m]);
state = m;
// You can put your state handling here,
// i.e. implement custom indication
}
}
void printDeviceBanner()
{
Blynk.printBanner();
DEBUG_PRINT("--------------------------");
DEBUG_PRINT(String("Product: ") + BLYNK_DEVICE_NAME);
DEBUG_PRINT(String("Firmware: ") + BLYNK_FIRMWARE_VERSION " (build " __DATE__ " " __TIME__ ")");
if (configStore.getFlag(CONFIG_FLAG_VALID)) {
DEBUG_PRINT(String("Token: ...") + (configStore.cloudToken+28));
}
DEBUG_PRINT(String("Device: ") + BLYNK_INFO_DEVICE);
DEBUG_PRINT(String("WiFi FW: ") + WiFi.firmwareVersion());
DEBUG_PRINT("--------------------------");
}
void runBlynkWithChecks() {
Blynk.run();
if (BlynkState::get() == MODE_RUNNING) {
if (!Blynk.connected()) {
if (WiFi.status() == WL_CONNECTED) {
BlynkState::set(MODE_CONNECTING_CLOUD);
} else {
BlynkState::set(MODE_CONNECTING_NET);
}
}
}
}
class Edgent {
public:
void begin()
{
indicator_init();
button_init();
config_init();
console_init();
printDeviceBanner();
if (configStore.getFlag(CONFIG_FLAG_VALID)) {
BlynkState::set(MODE_CONNECTING_NET);
} else if (config_load_blnkopt()) {
DEBUG_PRINT("Firmware is preprovisioned");
BlynkState::set(MODE_CONNECTING_NET);
} else {
BlynkState::set(MODE_WAIT_CONFIG);
}
}
void run() {
app_loop();
switch (BlynkState::get()) {
case MODE_WAIT_CONFIG:
case MODE_CONFIGURING: enterConfigMode(); break;
case MODE_CONNECTING_NET: enterConnectNet(); break;
case MODE_CONNECTING_CLOUD: enterConnectCloud(); break;
case MODE_RUNNING: runBlynkWithChecks(); break;
case MODE_OTA_UPGRADE: enterOTA(); break;
case MODE_SWITCH_TO_STA: enterSwitchToSTA(); break;
case MODE_RESET_CONFIG: enterResetConfig(); break;
default: enterError(); break;
}
}
};
Edgent BlynkEdgent;
BlynkTimer edgentTimer;
void app_loop() {
edgentTimer.run();
edgentConsole.run();
}
This is the code under “OTA.h”
#define OTA_FATAL(...) { BLYNK_LOG1(__VA_ARGS__); delay(1000); restartMCU(); }
#define USE_SSL
String overTheAirURL;
extern BlynkTimer edgentTimer;
BLYNK_WRITE(InternalPinOTA) {
overTheAirURL = param.asString();
overTheAirURL.replace("http://", "https://");
edgentTimer.setTimeout(2000L, [](){
// Start OTA
Blynk.logEvent("sys_ota", "OTA started");
// Disconnect, not to interfere with OTA process
Blynk.disconnect();
BlynkState::set(MODE_OTA_UPGRADE);
});
}
#include <ArduinoOTA.h> // only for InternalStorage
#if defined(USE_SSL)
WiFiClient* connectSSL(const String& host, const int port)
{
// Reuse Client
WiFiSSLClient* clientSSL = &_blynkWifiClient;
//WiFiSSLClient* clientSSL = new WiFiSSLClient();
if (!clientSSL->connect(host.c_str(), port)) {
OTA_FATAL(F("Connection failed"));
}
return clientSSL;
}
#endif
WiFiClient* connectTCP(const String& host, const int port)
{
WiFiClient* clientTCP = new WiFiClient();
if (!clientTCP->connect(host.c_str(), port)) {
OTA_FATAL(F("Client not connected"));
}
return clientTCP;
}
bool parseURL(String url, String& protocol, String& host, int& port, String& uri)
{
int index = url.indexOf(':');
if(index < 0) {
return false;
}
protocol = url.substring(0, index);
url.remove(0, (index + 3)); // remove protocol part
index = url.indexOf('/');
String server = url.substring(0, index);
url.remove(0, index); // remove server part
index = server.indexOf(':');
if(index >= 0) {
host = server.substring(0, index); // hostname
port = server.substring(index + 1).toInt(); // port
} else {
host = server;
if (protocol == "http") {
port = 80;
} else if (protocol == "https") {
port = 443;
}
}
if (url.length()) {
uri = url;
} else {
uri = "/";
}
return true;
}
void enterOTA() {
BlynkState::set(MODE_OTA_UPGRADE);
// Disconnect, not to interfere with OTA process
Blynk.disconnect();
String protocol, host, url;
int port;
DEBUG_PRINT(String("OTA: ") + overTheAirURL);
if (!parseURL(overTheAirURL, protocol, host, port, url)) {
OTA_FATAL(F("Cannot parse URL"));
}
DEBUG_PRINT(String("Connecting to ") + host + ":" + port);
Client* client = NULL;
if (protocol == "http") {
client = connectTCP(host, port);
#ifdef USE_SSL
} else if (protocol == "https") {
client = connectSSL(host, port);
#endif
} else {
OTA_FATAL(String("Unsupported protocol: ") + protocol);
}
client->print(String("GET ") + url + " HTTP/1.0\r\n"
+ "Host: " + host + "\r\n"
+ "Connection: keep-alive\r\n"
+ "\r\n");
uint32_t timeout = millis();
while (client->connected() && !client->available()) {
if (millis() - timeout > 10000L) {
OTA_FATAL("Response timeout");
}
delay(10);
}
// Collect headers
String md5;
int contentLength = 0;
while (client->available()) {
String line = client->readStringUntil('\n');
line.trim();
//DEBUG_PRINT(line); // Uncomment this to show response headers
line.toLowerCase();
if (line.startsWith("content-length:")) {
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
} else if (line.startsWith("x-md5:")) {
md5 = line.substring(line.lastIndexOf(':') + 1);
} else if (line.length() == 0) {
break;
}
delay(10);
}
if (contentLength <= 0) {
OTA_FATAL("Content-Length not defined");
}
if (!InternalStorage.open(contentLength)) {
client->stop();
OTA_FATAL("OTA begin failed");
}
DEBUG_PRINT("Flashing...");
int written = 0;
int prevProgress = 0;
uint8_t buff[256];
while (client->connected() && written < contentLength) {
delay(10);
timeout = millis();
while (client->connected() && !client->available()) {
delay(1);
if (millis() - timeout > 10000L) {
OTA_FATAL("Timeout");
}
}
int len = client->read(buff, sizeof(buff));
if (len <= 0) continue;
for (int i = 0; i<len; i++) {
InternalStorage.write(buff[i]);
}
written += len;
const int progress = (written*100)/contentLength;
if (progress - prevProgress >= 10 || progress == 100) {
BLYNK_PRINT.print(String("\r ") + progress + "%");
prevProgress = progress;
}
}
BLYNK_PRINT.println();
client->stop();
InternalStorage.close();
if (written != contentLength) {
OTA_FATAL(String("Write failed. Written ") + written + " / " + contentLength + " bytes");
}
DEBUG_PRINT("=== Update successfully completed. Rebooting.");
InternalStorage.apply();
}
Would appreciate some help, thanks.