I’m a hobbyist and been using the Arduino IDE for some years (although by no means an expert in C++ coding). I thought I would try out PlatformIO due to it’s debugging capabilities. I was able to get the blink program working so decided to move across a slightly more difficult sketch. After days of attempting to get it to compile, I went back to Arduino and was able to get it to compile in minutes! I’d really like to use the debugging capability, but about to give-up - So, this is one last plea for help!
The problem is with the OTA libraries. The compiler complain about functions that are clearly defined. I am even able to use the “go to definition” in VS code to go to them, but the compiler does not find them. I suspect, it has to do with how I am #Including the relevent files. Whilst I found several discussion on issue with libraries, I could not find a clear concise approach to including them.
I have a separate file with the OTA code to simplify the main line of logic (I’ve used this approach on numerous sketches in Arduino IDE). But also did try using the example OTA code and kept hitting an issue with NetworkUDP.h not being found. I would have thought the IDE would download it automatically.
The compiler log is below:
* Executing task in folder Irrigation controller: C:\Users\user\.platformio\penv\Scripts\platformio.exe run
Processing nodemcu-32s (platform: espressif32; board: nodemcu-32s; framework: arduino)
---------------------------------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/nodemcu-32s.html
PLATFORM: Espressif 32 (6.5.0) > NodeMCU-32S
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (esp-prog) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
- framework-arduinoespressif32 @ 3.20014.231204 (2.0.14)
- tool-esptoolpy @ 1.40501.0 (4.5.1)
- toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 37 compatible libraries
Scanning dependencies...
Dependency Graph
|-- ArduinoJson @ 7.0.0
|-- PubSubClient @ 2.8.0
|-- ArduinoOTA @ 1.1.0
|-- ESPmDNS @ 2.0.0
|-- WiFi @ 2.0.0
|-- Wire @ 2.0.0
Building in release mode
Compiling .pio\build\nodemcu-32s\src\main.cpp.o
In file included from src/main.cpp:24:
.pio/libdeps/nodemcu-32s/ArduinoOTA/src/ArduinoOTA.h:141:22: error: 'WiFiServer' was not declared in this scope
ArduinoOTAMdnsClass <WiFiServer, WiFiClient, WiFiUDP> ArduinoOTA;
^~~~~~~~~~
.pio/libdeps/nodemcu-32s/ArduinoOTA/src/ArduinoOTA.h:141:22: note: suggested alternative: 'Server'
ArduinoOTAMdnsClass <WiFiServer, WiFiClient, WiFiUDP> ArduinoOTA;
^~~~~~~~~~
Server
.pio/libdeps/nodemcu-32s/ArduinoOTA/src/ArduinoOTA.h:141:34: error: 'WiFiClient' was not declared in this scope
ArduinoOTAMdnsClass <WiFiServer, WiFiClient, WiFiUDP> ArduinoOTA;
^~~~~~~~~~
.pio/libdeps/nodemcu-32s/ArduinoOTA/src/ArduinoOTA.h:141:34: note: suggested alternative: 'DNSClient'
ArduinoOTAMdnsClass <WiFiServer, WiFiClient, WiFiUDP> ArduinoOTA;
^~~~~~~~~~
DNSClient
.pio/libdeps/nodemcu-32s/ArduinoOTA/src/ArduinoOTA.h:141:53: error: template argument 1 is invalid
ArduinoOTAMdnsClass <WiFiServer, WiFiClient, WiFiUDP> ArduinoOTA;
^
.pio/libdeps/nodemcu-32s/ArduinoOTA/src/ArduinoOTA.h:141:53: error: template argument 2 is invalid
In file included from src/main.cpp:26:
src/OTA.h: In function 'void setupOTA(const char*)':
src/OTA.h:34:14: error: request for member 'setHostname' in 'ArduinoOTA', which is of non-class type 'int'
ArduinoOTA.setHostname(fullhostname);
^~~~~~~~~~~
src/OTA.h:54:14: error: request for member 'onStart' in 'ArduinoOTA', which is of non-class type 'int'
ArduinoOTA.onStart([]() {
^~~~~~~
src/OTA.h: In lambda function:
src/OTA.h:56:20: error: request for member 'getCommand' in 'ArduinoOTA', which is of non-class type 'int'
if (ArduinoOTA.getCommand() == U_FLASH)
^~~~~~~~~~
src/OTA.h:56:36: error: 'U_FLASH' was not declared in this scope
if (ArduinoOTA.getCommand() == U_FLASH)
^~~~~~~
src/OTA.h: In function 'void setupOTA(const char*)':
src/OTA.h:64:14: error: request for member 'onEnd' in 'ArduinoOTA', which is of non-class type 'int'
ArduinoOTA.onEnd([]() {
^~~~~
src/OTA.h:67:14: error: request for member 'onProgress' in 'ArduinoOTA', which is of non-class type 'int'
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
^~~~~~~~~~
src/OTA.h:70:14: error: request for member 'onError' in 'ArduinoOTA', which is of non-class type 'int'
ArduinoOTA.onError([](ota_error_t error) {
^~~~~~~
src/OTA.h:70:25: error: 'ota_error_t' has not been declared
ArduinoOTA.onError([](ota_error_t error) {
^~~~~~~~~~~
src/OTA.h: In lambda function:
src/OTA.h:72:18: error: 'OTA_AUTH_ERROR' was not declared in this scope
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
^~~~~~~~~~~~~~
src/OTA.h:72:18: note: suggested alternative: 'UART_NO_ERROR'
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
^~~~~~~~~~~~~~
UART_NO_ERROR
src/OTA.h:73:23: error: 'OTA_BEGIN_ERROR' was not declared in this scope
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
^~~~~~~~~~~~~~~
src/OTA.h:73:23: note: suggested alternative: 'ESP_LOG_ERROR'
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
^~~~~~~~~~~~~~~
ESP_LOG_ERROR
src/OTA.h:74:23: error: 'OTA_CONNECT_ERROR' was not declared in this scope
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
^~~~~~~~~~~~~~~~~
src/OTA.h:74:23: note: suggested alternative: 'STA_CONNECTED_BIT'
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
^~~~~~~~~~~~~~~~~
STA_CONNECTED_BIT
src/OTA.h:75:23: error: 'OTA_RECEIVE_ERROR' was not declared in this scope
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
^~~~~~~~~~~~~~~~~
src/OTA.h:76:23: error: 'OTA_END_ERROR' was not declared in this scope
else if (error == OTA_END_ERROR) Serial.println("End Failed");
^~~~~~~~~~~~~
src/OTA.h:76:23: note: suggested alternative: 'UART_NO_ERROR'
else if (error == OTA_END_ERROR) Serial.println("End Failed");
^~~~~~~~~~~~~
UART_NO_ERROR
src/OTA.h: In function 'void setupOTA(const char*)':
src/OTA.h:79:14: error: request for member 'begin' in 'ArduinoOTA', which is of non-class type 'int'
ArduinoOTA.begin();
^~~~~
In file included from src/switch_panel.h:5,
from src/main.cpp:32:
src/switch.h: In member function 'void Switch::publishSwitchState()':
src/switch.h:148:5: warning: 'template<unsigned int N> class ArduinoJson::V700PB2::StaticJsonDocument' is deprecated: use JsonDocument instead [-Wdeprecated-declarations]
StaticJsonDocument<300> doc;
^~~~~~~~~~~~~~~~~~
In file included from .pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson.hpp:53,
from .pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson.h:9,
from src/main.cpp:30:
.pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson/compatibility.hpp:63:58: note: declared here
class ARDUINOJSON_DEPRECATED("use JsonDocument instead") StaticJsonDocument
^~~~~~~~~~~~~~~~~~
In file included from src/switch_panel.h:5,
from src/main.cpp:32:
src/switch.h: In member function 'void Switch::publishSwitchAttributes()':
src/switch.h:174:5: warning: 'template<unsigned int N> class ArduinoJson::V700PB2::StaticJsonDocument' is deprecated: use JsonDocument instead [-Wdeprecated-declarations]
StaticJsonDocument<300> doc;
^~~~~~~~~~~~~~~~~~
In file included from .pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson.hpp:53,
from .pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson.h:9,
from src/main.cpp:30:
.pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson/compatibility.hpp:63:58: note: declared here
class ARDUINOJSON_DEPRECATED("use JsonDocument instead") StaticJsonDocument
^~~~~~~~~~~~~~~~~~
src/main.cpp: In function 'void reconnect()':
src/main.cpp:165:20: error: request for member 'handle' in 'ArduinoOTA', which is of non-class type 'int'
ArduinoOTA.handle();
^~~~~~
src/main.cpp: In function 'void loop()':
src/main.cpp:215:14: error: request for member 'handle' in 'ArduinoOTA', which is of non-class type 'int'
ArduinoOTA.handle();
^~~~~~
src/main.cpp: In function 'int timerDuration()':
src/main.cpp:332:3: warning: 'template<unsigned int N> class ArduinoJson::V700PB2::StaticJsonDocument' is deprecated: use JsonDocument instead [-Wdeprecated-declarations]
StaticJsonDocument<200> doc;
^~~~~~~~~~~~~~~~~~
In file included from .pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson.hpp:53,
from .pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson.h:9,
from src/main.cpp:30:
.pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson/compatibility.hpp:63:58: note: declared here
class ARDUINOJSON_DEPRECATED("use JsonDocument instead") StaticJsonDocument
^~~~~~~~~~~~~~~~~~
src/main.cpp: In function 'void publishLog(String)':
src/main.cpp:353:3: warning: 'template<unsigned int N> class ArduinoJson::V700PB2::StaticJsonDocument' is deprecated: use JsonDocument instead [-Wdeprecated-declarations]
StaticJsonDocument<200> doc;
^~~~~~~~~~~~~~~~~~
In file included from .pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson.hpp:53,
from .pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson.h:9,
from src/main.cpp:30:
.pio/libdeps/nodemcu-32s/ArduinoJson/src/ArduinoJson/compatibility.hpp:63:58: note: declared here
class ARDUINOJSON_DEPRECATED("use JsonDocument instead") StaticJsonDocument
^~~~~~~~~~~~~~~~~~
Compiling .pio\build\nodemcu-32s\FrameworkArduino\esp32-hal-cpu.c.o
*** [.pio\build\nodemcu-32s\src\main.cpp.o] Error 1
============================================================== [FAILED] Took 17.12 seconds ==============================================================
* The terminal process "C:\Users\user\.platformio\penv\Scripts\platformio.exe 'run'" terminated with exit code: 1.
* Terminal will be reused by tasks, press any key to close it.
The sketch mainline.
/****************************************************************
* This sketch uses a switch panel as an irrigation controller
*
*
*
***************************************************************/
#include <Arduino.h>
//#define NUMBER_OF_REGISTERS 2
#define NUMBER_OF_SWITCHES 12
#define CLOCK_PIN 4
#define DATA_PIN 5
#define REVERSE_SWITCH 1 // 1 = true; 0 = false - used for relays that are off on high
#define LED_PIN 2
#define RAIN_SENSOR_PIN 14 //D5 on ESP8266
#define DEVICE_NAME "Irrigation controller"
#include <credentials.h>
//#include <WiFi.h>
//#include "WiFiOTA.h"
//#include <WiFi.h>
//#include <ESPmDNS.h>
//#include <NetworkUdp.h>
#include <ArduinoOTA.h>
#include <OTA.h>
//#include <stdlib.h>
//#include <mqtt_broker.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <Timer.h>
#include <switch_panel.h>
#include <rain_sensor.h>
int statusUpdateInterval = 1; // in minutes
int attributeUpdateInterval = 30; // in secs
int rainSensorUpdateInterval = 60; // in secs
const char *DEVICE_ID = DEVICE_NAME; // Name of our device, must be unique (For MQTT and OTA)
const char *PUB_LOG_TOPIC = "home/log"; // Topic for log
const char *SUB_TOPIC = "home/garden/" DEVICE_NAME "/request"; // for device requests
const char *PUB_STATE_TOPIC = "home/garden/" DEVICE_NAME; // Topic for device
IPAddress broker(192,168,86,234); // IP address of your MQTT broker PROD
//IPAddress broker(192,168,86,249); // IP address of your MQTT broker TEST
const char *USERNAME = mqttUSERID;
const char *PASSWORD = mqttPASSWORD;
const char *switchName[NUMBER_OF_SWITCHES] {
"z1 back fence",
"z2 buxus hedge",
"z3 back lawn 1",
"z4 back lawn 2",
"z5 bbq area",
"z6 balinese sanctuary",
"z7 small pond",
"z8 front lawn",
"z9 front plants",
"z10 shrubs around pond",
"z11 driveway plants",
"z12 large pond"
};
int maxDurations[NUMBER_OF_SWITCHES] {
30,
30,
20,
20,
30,
30,
10,
20,
30,
30,
30,
10
};
String response;
char* requestTopic;
bool requestArrived = false;
enum State {
OFF,
INITIALISING,
STANDBY,
IRRIGATION_ON,
UNAVAILABLE
};
State currentState = OFF;
enum Event {
INITIALISED,
REQUEST_ARRIVED
};
Event triggerEvent = INITIALISED;
enum RequestType {
INVALID,
TURN_ON,
TURN_OFF,
START_TIMER,
RESET_CONTROLLER
};
RequestType requestType = INVALID;
WiFiClient wclient;
uint16_t keepAlive = 21600; // mqtt keep connection alive for 6 hours - used in "setup"
PubSubClient mqttClient(wclient); // MQTT client
//MQTTBroker mqttBrocker(&wclient,),
//SwitchPanel switchPanel(DEVICE_ID, switchName[NUMBER_OF_SWITCHES], maxDurations[NUMBER_OF_SWITCHES], statusUpdateInterval, attributeUpdateInterval, PUB_STATE_TOPIC, &client);
SwitchPanel switchPanel(DEVICE_ID, &switchName[NUMBER_OF_SWITCHES], &maxDurations[NUMBER_OF_SWITCHES], &mqttClient, PUB_STATE_TOPIC, statusUpdateInterval, attributeUpdateInterval);
//const char* _deviceName, const char* _switchName[NUMBER_OF_SWITCHES], int _maxDuration[NUMBER_OF_SWITCHES], PubSubClient* _pubSubClient, const char * _deviceTopic, int _statusUpdateInterval = 1, int _attributeUpdateInterval = 10
RainSensor rainSensor("rain sensor", DEVICE_ID, rainSensorUpdateInterval, PUB_STATE_TOPIC, &mqttClient);
int interval = 2; //interval between switching on zones in seconds
Timer wateringDuration;
Timer statusUpdateIntervalTimer;
// Function definitions - the platformIO compiler requires function defintions before referred to
void publishLog(String);
void setRequestType();
void processRequest();
void eventHandler();
int switchIndex();
int timerDuration();
void setup();
///////////////////////////////////// Handle incomming messages from the broker
void callback(char* topic, byte* payload, unsigned int length) {
//String response;
for (int i = 0; i < length; i++) {
response += (char)payload[i];
}
requestTopic = topic;
requestArrived = true;
}
///////////////////////////////////////// Reconnect to client
void reconnect() {
// Loop until we're reconnected
while (!mqttClient.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if(mqttClient.connect(DEVICE_ID, USERNAME, PASSWORD)) {
mqttClient.subscribe(SUB_TOPIC);
publishLog("MQTT Connection re-established");
} else {
Timer timeBetweenAttempts;
timeBetweenAttempts.start(5000);
while (!timeBetweenAttempts.timeUp()){
ArduinoOTA.handle();
}
}
}
}
/////////////////////////////////////setup
void setup(){
currentState = INITIALISING;
pinMode(LED_PIN, OUTPUT); // Configure LED_PIN as an output
delay(100);
digitalWrite(LED_PIN, HIGH);
delay(100);
pinMode(RAIN_SENSOR_PIN, INPUT_PULLUP);
delay(100);
Serial.begin(115200);
delay(100);
setupOTA(DEVICE_ID);
//************ Setup MQTT server *************
mqttClient.setServer(broker, 1883);
mqttClient.setKeepAlive(keepAlive); // keep mqtt connection alive for x seconds
mqttClient.setCallback(callback); // Initialize the callback routine
switchPanel.turnAllOff();
currentState = STANDBY;
for (int i=0; i<5; i++){
digitalWrite(LED_PIN, LOW);
delay(250);
digitalWrite(LED_PIN, HIGH);
delay(750);
}
publishLog("Initialisation complete");
digitalWrite(LED_PIN, LOW);
delay(100);
}
////////////////////////////////
void loop() {
ArduinoOTA.handle();
delay(20); // OTA seems to work better when this is at least 20
// Capture any trigger events
requestArrived = false;
if (!mqttClient.connected()){reconnect(); } // Reconnect if connection is lost
mqttClient.loop(); // MQTT subscription read. (see callback)
if (requestArrived){
triggerEvent = REQUEST_ARRIVED;
eventHandler();
response = "";
requestArrived = false;
}
if (switchPanel.switchesOn()){
currentState = IRRIGATION_ON;
} else if (!UNAVAILABLE){
currentState = STANDBY;
}
yield();
}
//////////////////////////////////////////////////////////////
void eventHandler(){
delay(10); // provide a time lag between readings on sensors
digitalWrite(LED_PIN, LOW); // turn LED ON
switch (triggerEvent) {
case REQUEST_ARRIVED:
processRequest();
break;
}
digitalWrite(LED_PIN, HIGH); // turn LED OFF
}
////////////////////////////////////////////////////////////////////////
void processRequest(){
publishLog(response);
setRequestType();
switch(requestType){
case TURN_ON:
switchPanel.turnAllOff();
delay(interval * 1000);
switchPanel.turnOn(switchIndex());
currentState = IRRIGATION_ON;
break;
case TURN_OFF:
switchPanel.turnAllOff();
currentState = STANDBY;
break;
case START_TIMER:
switchPanel.startTimer(switchIndex(), timerDuration());
currentState = STANDBY;
break;
case RESET_CONTROLLER:
ESP.restart();
break;
}
}
/************************************************************************
* The request message can be:
* 1. "on" Turn switch on
* 2. "off" Turn switch off
* 3. {"Timer duration" = nnnn } start timer for specified duration
*
* *********************************************************************/
void setRequestType() {
if (response == "on"){
requestType = TURN_ON;
} else if (response == "off")
{
requestType = TURN_OFF;
} else if ((String)response[0] == "{")
{
requestType = START_TIMER;
} else if (response == "reset")
{
requestType = RESET_CONTROLLER;
} else
{
requestType = INVALID;
}
}
int switchIndex(){
int i = 0;
for (i=0; i < NUMBER_OF_SWITCHES; i++){
String switchTopic = "home/garden/" DEVICE_NAME "/" + (String)switchName[i] + "/request";
if (strcmp(requestTopic, switchTopic.c_str()) == 0){
break;
}
}
return i;
}
int timerDuration(){
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, response);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return 0;
}
String timerDuration = doc["Timer duration"];
int i = timerDuration.toInt();
return atoi(timerDuration.c_str());
}
void publishLog(String p_message) {
// create a JSON object
StaticJsonDocument<200> doc;
doc["device"] = DEVICE_ID;
doc["message"] = p_message;
serializeJsonPretty(doc, Serial);
//delay(100);
Serial.println(" ");
char data[200];
serializeJson(doc, data, sizeof(data)+ 1);
// doc.printTo(data, doc.measureLength() + 1);
if (!mqttClient.connected()) {reconnect();} // Reconnect if connection to MQTT server is lost
mqttClient.publish(PUB_LOG_TOPIC, data, true);
yield();
}
The separate code for OTA
#ifndef OTA_H
#define OTA_H
#ifdef ESP32
#include <WiFi.h>
#include <ESPmDNS.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#endif
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <credentials.h>
const char* ssid = mySSID;
const char* password = myPASSWORD;
#if defined(ESP32_RTOS) && defined(ESP32)
void taskOne( void * parameter )
{
ArduinoOTA.handle();
delay(3500);
}
#endif
void setupOTA(const char* nameprefix) {
const int maxlen = 40;
char fullhostname[maxlen];
uint8_t mac[6];
WiFi.macAddress(mac);
snprintf(fullhostname, maxlen, "%s-%02x%02x%02x", nameprefix, mac[3], mac[4], mac[5]);
ArduinoOTA.setHostname(fullhostname);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
// Port defaults to 3232
// ArduinoOTA.setPort(3232);
// No authentication by default
// ArduinoOTA.setPassword("admin");
// Password can be set with it's md5 value as well
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
Serial.println("OTA Initialized");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("MAC: ");
Serial.println(WiFi.macAddress());
Serial.println();
#if defined(ESP32_RTOS) && defined(ESP32)
xTaskCreate(
ota_handle, /* Task function. */
"OTA_HANDLE", /* String with name of task. */
10000, /* Stack size in bytes. */
NULL, /* Parameter passed as input of the task */
1, /* Priority of the task. */
NULL); /* Task handle. */
#endif
}
#endif
platformIO ini
[env:nodemcu-32s]
platform = espressif32
board = nodemcu-32s
framework = arduino
monitor_speed = 115200
debug_tool = esp-prog
debug_init_break = tbreak setup
lib_deps =
bblanchon/ArduinoJson@^7.0.0
knolleary/PubSubClient@^2.8
jandrassy/ArduinoOTA@^1.1.0
Any help is much appreciated.
Thanking you in advance.