JAndrassy / ArduinoOTA

Arduino library to upload sketch over network to Arduino board with WiFi or Ethernet libraries
GNU Lesser General Public License v2.1
437 stars 89 forks source link

Sketch flashing is done but Arduino runs the old sketch. #133

Closed RStaes closed 2 years ago

RStaes commented 2 years ago

Hello,

i have this problem: I have an Arduino Mega 2560 and flashed the optiboot bootloader to it with an Uno as programmer. All went fine. When i use 'Upload using programmer' I get no error and the message below is telling me all went fine. But when the Mega restart it just runs the old sketch.

Connecting to board ...  done
Uploading sketch ...  done
Flashing sketch ...  done
OK
Sketch uploaded successfully

What am I doing wrong?

Sketch:

#include <Ethernet.h>
#include <ArduinoOTA.h>
#include <SPI.h>
#include "PubSubClient.h"
#include <DallasTemperature.h>
#include <avr/wdt.h> // for Watchdog

#define CLIENT_ID       "meterkast"
#define PUBLISH_DELAY   10000
#define FAST_MODE // 50 times faster execution; consider to disconnect your real CV/Pump!

// In Normal operation to loop runs 10 times per second; so 10 counts/second (600 represents ca 1 minute)
#define VALVE_TIME             3000L    // 5 minutes to open/close a valve (on the safe site; takes typically 3 to 5 minutes)
#ifdef  FAST_MODE
#define PUMP_MAINTENANCE_TIME  108000L // For evaluation, activates Floor Unit pump maintenance run once per 4 minutes (time stamp 3 hours)
#else
#define PUMP_MAINTENANCE_TIME  1300000L // Activates Floor Unit pump maintenance run once per 36 hours. Needed to keep pump working
#endif
#define PUMP_ACTIVATION_TIME   5000L    // Activates the pump for ca 8 minutes (10 seconds in test mode)
#define COOLDOWN_TIME          18000L   // When heating is done, continue water circulation for another 30 minutes (40 seconds in test mode)
                                        // This enables further dissipation the heat into the floor (typically takes 15 to 30 minutes)

#include "./Devices.h" // valves, pumps, thermostat classes (use the constants defines above)

#define HEATER_PIN      33 // output to a Relay that is wired with the Thermostat input of your heating system
#define FU_PUMP_PIN     25 // output to a Relay that switches the Floor Unit Pump
#define PORCH_RELAY     24 // Zone 1: output to a Relay that controls the Valve(s)
#define LIVING_RELAY    27 // Zone 2: output to a Relay that controls the Valve(s)
#define PLAYROOM_RELAY  26 // Zone 3: output to a Relay that controls the Valve(s)
#define OFFICE_RELAY    29 // Zone 4: output to a Relay that controls the Valve(s)
#define BATHROOM_RELAY  32 // Zone 5: output to a Relay that controls the Valve(s)
#define STORAGE_RELAY   31 // Zone 6: output to a Relay that controls the Valve(s)
#define UPSTAIRS_RELAY  34 // Zone 7: output to a Relay that controls the Valve(s)

#define HEATING_LED     41 // On when heating, Alternates during cooldown, is Off in idle mode
#define INDICATION_LED  13 // Alternates the on board LED to indicate board runs; can be easily removed to free an extra IO pin!!

// Configure the Floor Unit Zones/rooms. Each zone/room owns a name, valve and thermostat:
#define NR_ZONES 7
#define NR_ZONETHERMOSTATS 7

byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip2(192, 168, 1, 64);
EthernetClient ethClient;
PubSubClient mqttClient(ethClient);
long previousMillis;
const int controlPin[] = {25,24,27,26,29,32,31,34,33,36,35,38,37,40,39,41}; // define pins
const int triggerType = LOW;// your relay type
int deviceCount = 0;
int Counter = 0;
bool Thermo           = false;  
float IsTemp          ;
float SetTemp         ;
String IsTopic        = "/is";
String SetTopic       = "/setpoint";
String ModeTopic      = "/mode";                 //0 = “off”, 1 = “heat”, 2 = “cool”
String ModeStateTopic = "/modestate"; 
String ActionTopic    = "/action";
String Action         = "";
String Mode           = "";
String ModeState      = "";

struct Zone {
  String name;
  Valve valve;
  bool thermostat;
  float IsTemp;
  float SetTemp;
  String IsTopic;
  String SetTopic;
  String ModeTopic;         //0 = “off”, 1 = “heat”, 2 = “cool”
  String ActionTopic;
  String ModeStateTopic;
  String Action;
  String Mode;
  String ModeState;
};
Zone Zones[NR_ZONES] = { {"portiek",    Valve(PORCH_RELAY,    "Portiek Relay"),     Thermo, IsTemp, SetTemp, IsTopic, SetTopic, ModeTopic, ActionTopic, ModeStateTopic, Action, Mode, ModeState},
                         {"woonkamer",  Valve(LIVING_RELAY,   "Woonkamer Relay"),   Thermo, IsTemp, SetTemp, IsTopic, SetTopic, ModeTopic, ActionTopic, ModeStateTopic, Action, Mode, ModeState},
                         {"speelkamer", Valve(PLAYROOM_RELAY, "Speelkamer Relay"),  Thermo, IsTemp, SetTemp, IsTopic, SetTopic, ModeTopic, ActionTopic, ModeStateTopic, Action, Mode, ModeState},
                         {"kantoor",    Valve(OFFICE_RELAY,   "Kantoor Relay"),     Thermo, IsTemp, SetTemp, IsTopic, SetTopic, ModeTopic, ActionTopic, ModeStateTopic, Action, Mode, ModeState},
                         {"badkamer",   Valve(BATHROOM_RELAY, "Badkamer Relay"),    Thermo, IsTemp, SetTemp, IsTopic, SetTopic, ModeTopic, ActionTopic, ModeStateTopic, Action, Mode, ModeState},
                         {"berging",    Valve(STORAGE_RELAY,  "Berging Relay"),     Thermo, IsTemp, SetTemp, IsTopic, SetTopic, ModeTopic, ActionTopic, ModeStateTopic, Action, Mode, ModeState},
                         {"boven",      Valve(UPSTAIRS_RELAY, "Boven Relay"),       Thermo, IsTemp, SetTemp, IsTopic, SetTopic, ModeTopic, ActionTopic, ModeStateTopic, Action, Mode, ModeState}
                         };

LED           iLED(INDICATION_LED, "Indicator LED"); // can be removed if you run out of IO's
LED           hLED(HEATING_LED, "Heating LED");
Manipulator   CV(HEATER_PIN, "CV Heater");
Pump          FUPump(FU_PUMP_PIN, "Floor Unit Pump");

void printConfiguration() {
   Serial.println("------ Board Configuration: ---------");
   iLED.Print();
   hLED.Print();
   CV.Print();
   FUPump.Print();
   for(int i=0; i<NR_ZONES; i++) {
      Serial.print("Zone["); Serial.print(i+1); 
      Serial.print("]: "); Serial.print(Zones[i].name);
      Serial.print(" - "); Zones[i].valve.Print();
      //Serial.print(" - "); Zones[i].thermostat.Print();
   }
   Serial.println("-------------------------------------");
}

// state machine, with both transition and state handling actions
class State
{
  public:
  enum states {
    idle,
    on,
    cooldown
  };

  private:
  //vars
  states _State;
  unsigned long cooldownCount;

  public: 
  //constructor
  StateMAchine()   {
    _State = idle;
  }

  // Getter
  states const& operator()() const {
      return _State;    
  }

  // Setter
  void operator()(states const& newState) {
      printTimeStamp();
      Serial.print(": State change from [");
      Print();
      _State = newState;
      Serial.print("] to [");
      Print();
      Serial.println("]");
      // deal with transition actions to the new state
      switch(_State)
      {
       case idle:
          hLED.Off();
          CV.Off();  // stop heating
          FUPump.Off(); 
          allValvesOff();
          break;
       case on:
          hLED.On();
          CV.On(); // start heating, but Floor unit pump has to wait till at least one zone is open
          break;
       case cooldown:
          CV.Off();  // stop heating
          allValvesOn(); // open all zones for cooldown; pump has to wait for this
          break;  
       default: 
         Serial.println("WARNING Unhandled State transition");
         break;
      }
  }

  // Do the state handling; to be called repatively by the loop()  
  void doProcessingActions() {
    switch(_State) {
       case on:
        onProcessing(); // As long heating is requested open/close zones matching the heating requests
        break;    
      case cooldown:
        coolDownProcessing(); // take 30 minutes to dissipate remaing Heat into the floor
        break;
      case idle:
        idleProcessing(); // operate pumps/valves once per day
        break;
      default: 
        Serial.println("ERROR Unhandled State");
        break;
    }
  }

  void setCoolDownNeeded() {
    cooldownCount = COOLDOWN_TIME;
  }
  bool whileCoolDownNeeded() { // down counts the time
     if (cooldownCount > 0) {
        cooldownCount--;
     }
     return checkCoolDownNeeded();
  }
  bool checkCoolDownNeeded() {
     return (cooldownCount> 0);
  }

  void Print()   {
    switch(_State)
    {
     case idle:
        Serial.print("idle");
        break;
     case on:
        Serial.print("on");
        break;
     case cooldown:
         Serial.print("cooldown");
        break;  
    }
  }
};

// The global state machine
State    CVState;

void setup(void)
{ 
  Serial.begin(9600);
  SetPins();
  SetEthernet();
  printTimeStamp();
  Serial.print(": ");
  #ifdef FAST_MODE
    Serial.println("CV Zone Controller started in TestMode!\n"
                  " - Board time runs ca 50 times faster\n"
                  " - Pump maintenance cycle runs ever 3 hours instead once per 36 hours");
  #else
    Serial.println("CV Zone Controller started. Time stamps (dd:hh:mm:ss)");
  #endif
  Serial.println(" - Time stamps format (dd:hh:mm:ss)");
  printConfiguration();
  wdt_enable(WDTO_4S);  // Watchdog: reset board after eight seconds, if no "pat the dog" received
  // start the OTEthernet library with internal (flash) based storage
  ArduinoOTA.begin(Ethernet.localIP(), "arduino", "password", InternalStorage);
  ArduinoOTA.beforeApply(shutdownwdt);
}

void loop(void){
  #ifdef FAST_MODE
    delay(2); // 50 times faster so minutes become roughly seconds for debugging purpose; so every count for cooldown or idle is 0.002 second
  #else
    delay(100); // Normal operation: loops approx 10 times per second; so every count for cooldown or idle is 0.1 second
  #endif

//  if (millis() - previousMillis > PUBLISH_DELAY) {
//    
//    CheckThermostatOn();
//    previousMillis = millis();
//  }
  mqttClient.loop();
  mqttReconnect();
  iLED.Alternate();
  FUPump.Update();
  for (int i=0; i<NR_ZONES; i++) {
    // Update valve administration for transition times to open/close
    Zones[i].valve.Update();
  }
  // Reset the WatchDog timer (pat the dog)
  wdt_reset();
  // check for updates
  ArduinoOTA.poll();
  // Do the state handling
  CVState.doProcessingActions();

}

void mqttReconnect() {
  //Make sure we stay connected to the mqtt broker
  if (!mqttClient.connected()) {
    mqttConnect();
  }
  if (!mqttClient.loop()) {
    mqttClient.connect(CLIENT_ID, "mqtt-user", "Robin81");
  }
}

void mqttConnect() {
  mqttClient.setServer("192.168.1.63", 1883);
  while (!mqttClient.connected()) {
    Serial.print(F("MQTT connecting..."));
    mqttClient.setCallback(callback);

  if (mqttClient.connect(CLIENT_ID, "mqtt-user", "Robin81")) {
    // connection succeeded
    Serial.println("Connected ");
    for (int i=0; i<NR_ZONES; i++) {
      String str = Zones[i].name + Zones[i].SetTopic; 
      int str_len = str.length() + 1; 
      char char_array[str_len];
      str.toCharArray(char_array, str_len);
      mqttClient.subscribe(char_array);
      str = Zones[i].name + Zones[i].ModeTopic; 
      str_len = str.length() + 1; 
      char_array[str_len];
      str.toCharArray(char_array, str_len);
      mqttClient.subscribe(char_array);
      str = Zones[i].name + Zones[i].IsTopic; 
      str_len = str.length() + 1; 
      char_array[str_len];
      str.toCharArray(char_array, str_len);
      mqttClient.subscribe(char_array);
    }
  } 
  else {
    Serial.println("Connection failed ");
  }
  }
}

void sendData() {
  if (mqttClient.connect(CLIENT_ID)) {    
    for (int i=0; i<NR_ZONES; i++) {
      mqttClient.publish((Zones[i].name + Zones[i].ActionTopic).c_str(), String(Zones[i].Action).c_str());
      mqttClient.publish((Zones[i].name + Zones[i].ModeStateTopic).c_str(), String(Zones[i].ModeState).c_str());
      delay(100);
    }
  printTimeStamp();
  Serial.print(": ");
  Serial.println("Data send");
  }
}

////////////////////////////////////////////////////////////////////
// Processing Methods for each CV State
/////////////////////////////////////////

void  onProcessing() {
  if (ProcessThermostats())  { // returns true if at least one of the thermostats is on (switch closed) => stay in this state
    if (FloorPumpingAllowed())   {
       FUPump.On();
    }
    else {
       FUPump.Off(); 
    }
  }
  else if ( CVState.checkCoolDownNeeded() ) {  // Continue in cooldown state to keep pump running for a while
      CVState(State::cooldown); 
  }
  else  {  // skip cooldown for floor unit, go back to idle
      CVState(State::idle); 
  }
}

void coolDownProcessing() {
  hLED.Alternate();
  if (HeatingRequested()) {   // returns true when one of the thermostats is closed
    CVState(State::on);
  }
  else  {
    if ( CVState.whileCoolDownNeeded() ) {
      if (FloorPumpingAllowed()) {
         FUPump.On();
      } else {
         FUPump.Off();  
      }        
    }
    else {
      CVState(State::idle);
    }
  }
}

void idleProcessing() 
{

  if (HeatingRequested())  {    // returns true when one of the thermostats is closed
    CVState(State::on);
  }
  else
  {
    // During idle period this check will activate the Floor Unit Pump for 8 minutes per 36 hours to keep them operatable
    if ( FUPump.doMaintenanceRun()) {
      if (FUPump.IsOff()) {
        if ( allValvesOpen() == false ) { // start opening just once
          printTimeStamp(); Serial.println(": Start daily cycle for Floor Unit Pump; open valves: ");
          allValvesOn();
        }
        if (FloorPumpingAllowed()) { 
          // this takes ca 5 minutes after activating the valves (6 seconds in test mode)
          printTimeStamp(); Serial.println(": Start daily cycle for Floor Unit Pump; start pump ");
          FUPump.On(); 
        }

      }
    } 
    else if (FUPump.IsOn()) {  // no Maintenance needed. So stop pump if still running
        printTimeStamp(); Serial.println(": Stop daily cycle for Floor Unit Pump; stop pump and close valves");
        FUPump.Off();
        allValvesOff();
    }
  }
}

////////////////////////////////////////////////////////////////////
// Helper Methods used by the State handlers
/////////////////////////////////////////

void allValvesOff() {
  for (int i=0; i<NR_ZONES; i++) {
    Zones[i].valve.Off();
  }    
}

void allValvesOn() {
  for (int i=0; i<NR_ZONES; i++) {
    Zones[i].valve.On();
  }    
}

bool allValvesOpen() {
  for (int i=0; i<NR_ZONES; i++) {
    if ( Zones[i].valve.IsOff() ) {
       return false;
    }
  }
  return true;
}

bool FloorPumpingAllowed() 
{
  // returns true if at least one zone is open, taking Valve transition into account
  for (int i=0; i<NR_ZONES; i++) {
    if (Zones[i].valve.ValveIsOpen() ) {
      return true;
    }
  }
  return false; // all valves are closed
}

bool ProcessThermostats() // returns true when one of the thermostats is closed
{                         // (De-)Activates Floor zones
   bool heating=false;
   bool requested[NR_ZONES]; 

   for (int i=0; i<NR_ZONES; i++) {
     // record heating requests only once to avoid race conditions due changes in between
     requested[i] = Zones[i].thermostat;
     if ( requested[i] ) {
       heating = true;
       CVState.setCoolDownNeeded(); // remember if there was a request for heating a floor unit zone
     }
   }
   for (int i=0; i<NR_ZONES; i++) {
     if ( requested[i] ) {
       // Selectively open valves for zones that request heating 
       Zones[i].valve.On();
     }
     else if (heating) {
       // Selectively close valves for zones that don't require heating anymore
       // Only close them if heating is still required because in cooldown all zones need to be open
       Zones[i].valve.Off();
     }
   }
   return heating;
}

bool HeatingRequested()
{
  for (int i=0; i<NR_ZONES; i++) {
    if (Zones[i].thermostat == true) {
      return true;
    }
  }
  return false; // all Thermostats are open (no heating needed)
}

void printTimeStamp() {
  #ifdef FAST_MODE
    // 50 times faster; represent the time it would be in normal mode
     unsigned long seconds = millis()/(unsigned long)20;
  #else
    // Normal operation
     unsigned long seconds = millis()/(unsigned long)1000;
  #endif
    unsigned long minutes, hours, days;
    minutes = seconds / 60L;
    seconds %= 60L; 
    hours = minutes / 60L;
    minutes %= 60L;
    days = hours / 24L;
    hours %= 24L;
    char time[30]; 
    sprintf(time, "%02d:%02d:%02d:%02d", (int)days, (int)hours, (int)minutes, (int)seconds);
    Serial.print(time);
}

void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';  
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  for (int i=0; i<NR_ZONES; i++) {
    if (String(topic) == Zones[i].name + Zones[i].SetTopic) {
      Serial.println(String(Zones[i].SetTemp,1));
      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");

      Serial.println("");
      Serial.println((char *)payload);
      Zones[i].SetTemp = atof((char *)payload);
    }
    else if (String(topic) == Zones[i].name + Zones[i].ModeTopic) {
      if (strcmp(((char *)payload), "off") == 0){
        Zones[i].ModeState = "off";
      }
      else if (strcmp(((char *)payload), "heat") == 0){
        Zones[i].ModeState = "heat";
      }
      else if (strcmp(((char *)payload), "cool") == 0){
        Zones[i].ModeState = "cool";
      }
    }
    else if (String(topic) == Zones[i].name + Zones[i].IsTopic) {
      Serial.println(String(Zones[i].IsTemp,1));
      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");

      Serial.println("");
      Serial.println((char *)payload);
      Zones[i].IsTemp = atof((char *)payload);
    }
  }
  if (String(topic) == "ha/status") {
      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");

  }
  CheckThermostatOn();
}
void SetPins(){
  Serial.println("SetPins2");
  for(int i=0; i<16; i++)
  {
    pinMode(controlPin[i], OUTPUT);// set pin as output
    if(triggerType ==LOW){
      digitalWrite(controlPin[i], HIGH); // set initial state OFF for low trigger relay
    }else{
       digitalWrite(controlPin[i], LOW); // set initial state OFF for high trigger relay     
    }
  }
}
void SetEthernet(){
  Serial.println("SetEthernet");  
  Ethernet.begin(mac);
  Serial.print("IP address: ");
  Serial.println(Ethernet.localIP());
}

void CheckThermostatOn(){
  for (int i=0; i<NR_ZONES; i++) {
    if (Zones[i].ModeState == "heat"){
      if (Zones[i].IsTemp < (Zones[i].SetTemp)){
      Zones[i].thermostat = true;
      Zones[i].Action = "heating";
      }
      else if (Zones[i].IsTemp > (Zones[i].SetTemp)){
        Zones[i].thermostat = false;
        Zones[i].Action = "idle";
      }
      else {
//        Zones[i].Action = "idle";      
      }
    }
    else if (Zones[i].ModeState == "off"){
        Zones[i].thermostat = false;
        Zones[i].Action = "off";
    }
  }
//  PrintZones();
  sendData();
}
void PrintZones(){
  for (int i=0; i<NR_ZONES; i++) {
    Serial.println(Zones[i].name);
    Serial.println(Zones[i].IsTemp);
    Serial.println(Zones[i].SetTemp);
    Serial.println(Zones[i].Action);
    Serial.println(Zones[i].Mode);
    Serial.println(Zones[i].ModeState);
    Serial.println("");
  }
}
void shutdownwdt() {
wdt_disable();
}
JAndrassy commented 2 years ago

what Optiboot did you flash? can you please show me the upload command line? what OS do you use?

RStaes commented 2 years ago

I’m using The latent from your “my hardware” folder. https://github.com/jandrassy/my_boards/blob/master/avr/bootloaders/optiboot8/optiboot_atmega2560.hex I use Arduino IDE on Windows 10.

"C:\\Users\\Robin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "C:\\Users\\Robin\\AppData\\Local\\Temp\\arduino_build_944869/Zoneverwarming4.ino.elf"
Sketch uses 37640 bytes (14%) of program storage space. Maximum is 261120 bytes.
Global variables use 3015 bytes (36%) of dynamic memory, leaving 5177 bytes for local variables. Maximum is 8192 bytes.
C:\Users\Robin\Documents\Arduino\hardware\my_boards-master/tools/arduinoOTA.exe -address 192.168.1.119 -port 65280 -t 61 -username arduino -password password -sketch C:\Users\Robin\AppData\Local\Temp\arduino_build_944869/Zoneverwarming4.ino.bin -upload /sketch -b 
JAndrassy commented 2 years ago

turn off the watchdog for a test

RStaes commented 2 years ago

I did, same result.

JAndrassy commented 2 years ago

I had a problem with OTA caused by Linux shell some weeks ago, so I tested the OTA upload to Mega and after I solved the command line problem the upload worked without problems. Others sometime report problems and we solve them and it works. Usual problems are those mentioned in troubleshooting section, watchdog and self reset problems on some derivative Mega.

RStaes commented 2 years ago

Ok, but it worked before...

The error is not in the sketch I think. When i upload this sketch with USB it runs. Then when I change text in serialprint and upload the sketch with programmer it is still not working. I think something is wrong with the programmer.

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoOTA.h>

//#define Serial SerialUSB

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };

void setup() {
  //Initialize serial:
  Serial.begin(9600);
  while (!Serial);

  // start the Ethernet connection:
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
  } else {
    Serial.print("  DHCP assigned IP ");
    Serial.println(Ethernet.localIP());
  }

  // start the OTEthernet library with internal (flash) based storage
  ArduinoOTA.begin(Ethernet.localIP(), "arduino", "password", InternalStorage);
}

void loop() {
  // check for updates
  ArduinoOTA.poll();

  // add your normal loop code below ...
}
JAndrassy commented 2 years ago

can you try the upload over network port?

RStaes commented 2 years ago

How can I do that? Under Tools>Port there is no network port.

JAndrassy commented 2 years ago

with Ethernet library it should be possible to get the network port. try every trick you find with google. I usually try to restart Arduino IDE, restart the network interface, restart the OS (computer). But maybe you need to install Bonjour into Windows.

RStaes commented 2 years ago

I'm sorry to bother you again...

Ok, now when I upload the sketch to the network port after compiling a window pops up where I have to enter a password. I guess it is "password" since that's the one in the sketch. Now I get this error:

{network_cmd} -address 192.168.1.120 -port 65280 -username arduino -password password -sketch C:\Users\Robin\AppData\Local\Temp\arduino_build_844495/Zoneverwarming_boven.ino.bin -upload /sketch -b 
java.io.IOException: Cannot run program "{network_cmd}": CreateProcess error=2, Het systeem kan het opgegeven bestand niet vinden
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at processing.app.helpers.ProcessUtils.exec(ProcessUtils.java:26)
    at cc.arduino.packages.Uploader.executeUploadCommand(Uploader.java:129)
    at cc.arduino.packages.uploaders.GenericNetworkUploader.uploadUsingPreferences(GenericNetworkUploader.java:99)
    at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
    at processing.app.SketchController.upload(SketchController.java:732)
    at processing.app.SketchController.exportApplet(SketchController.java:703)
    at processing.app.Editor$UploadHandler.run(Editor.java:2055)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: CreateProcess error=2, Het systeem kan het opgegeven bestand niet vinden
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(ProcessImpl.java:386)
    at java.lang.ProcessImpl.start(ProcessImpl.java:137)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 8 more

On google I can not find something that causes this error.

JAndrassy commented 2 years ago

there is a bug in Arduino AVR core 1.8.4 with OTA settings. as you see {network_cmd} is not replaced. use 1.8.3 or do this fix: https://github.com/arduino/ArduinoCore-avr/commit/525be9e725744c29f8c3b3fa4c216ce4f768e035

and AVR core 1.8.5 is already on its way to Boards Manager. maybe in a few days, maybe in a few hours.