diff --git a/.gitignore b/.gitignore
index 086b25d..ded71c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,8 +10,8 @@ sdkconfig.old
 
 
 # React
-react-app/build
-react-app/.pnp
+**/react-app/build
+**/react-app/.pnp
 .pnp.js
 node_modules
 
diff --git a/board_control/CMakeLists.txt b/board_control/CMakeLists.txt
new file mode 100644
index 0000000..c88e7f2
--- /dev/null
+++ b/board_control/CMakeLists.txt
@@ -0,0 +1,9 @@
+# For more information about build system see
+# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
+# The following five lines of boilerplate have to be in your project's
+# CMakeLists in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+set(EXTRA_COMPONENT_DIRS "../components ../common")
+project(armchair_controlBoard)
diff --git a/main/CMakeLists.txt b/board_control/main/CMakeLists.txt
similarity index 69%
rename from main/CMakeLists.txt
rename to board_control/main/CMakeLists.txt
index 92ed0e1..72a232c 100644
--- a/main/CMakeLists.txt
+++ b/board_control/main/CMakeLists.txt
@@ -1,18 +1,13 @@
 idf_component_register(
     SRCS 
         "main.cpp"
-        "motordrivers.cpp"
-        "motorctl.cpp"
         "config.cpp"
         "joystick.cpp"
-        "buzzer.cpp"
         "control.cpp"
         "button.cpp"
-        "fan.cpp"
-        "wifi.c"
         "http.cpp"
         "auto.cpp"
-		"currentsensor.cpp"
+		"uart.cpp"
     INCLUDE_DIRS 
         "."
     )
diff --git a/board_control/main/auto.cpp b/board_control/main/auto.cpp
new file mode 100644
index 0000000..0dc94aa
--- /dev/null
+++ b/board_control/main/auto.cpp
@@ -0,0 +1,89 @@
+#include "auto.hpp"
+#include "config.hpp"
+
+//tag for logging
+static const char * TAG = "automatedArmchair";
+
+
+//=============================
+//======== constructor ========
+//=============================
+automatedArmchair::automatedArmchair(void) {
+    //create command queue
+    commandQueue = xQueueCreate( 32, sizeof( commandSimple_t ) ); //TODO add max size to config?
+}
+
+
+//FIXME motorLeft, Right not available, needs rework to work with uart only
+
+//  //==============================
+//  //====== generateCommands ======
+//  //==============================
+//  motorCommands_t automatedArmchair::generateCommands(auto_instruction_t * instruction) {
+//      //reset instruction
+//      *instruction = auto_instruction_t::NONE;
+//      //check if previous command is finished
+//      if ( esp_log_timestamp() > timestampCmdFinished ) {
+//          //get next command from queue
+//          if( xQueueReceive( commandQueue, &cmdCurrent, pdMS_TO_TICKS(500) ) ) {
+//              ESP_LOGI(TAG, "running next command from queue...");
+//              //copy instruction to be provided to control task
+//              *instruction = cmdCurrent.instruction;
+//              //set acceleration / fading parameters according to command
+//              motorLeft.setFade(fadeType_t::DECEL, cmdCurrent.fadeDecel);
+//              motorRight.setFade(fadeType_t::DECEL, cmdCurrent.fadeDecel);
+//              motorLeft.setFade(fadeType_t::ACCEL, cmdCurrent.fadeAccel);
+//              motorRight.setFade(fadeType_t::ACCEL, cmdCurrent.fadeAccel);
+//              //calculate timestamp the command is finished
+//              timestampCmdFinished = esp_log_timestamp() + cmdCurrent.msDuration;
+//              //copy the new commands
+//              motorCommands = cmdCurrent.motorCmds;
+//          } else { //queue empty
+//              ESP_LOGD(TAG, "no new command in queue -> set motors to IDLE");
+//              motorCommands = motorCmds_bothMotorsIdle;
+//          }
+//      } else { //previous command still running
+//          ESP_LOGD(TAG, "command still running -> no change");
+//      }
+//  
+//      //TODO also return instructions via call by reference
+//      return motorCommands;
+//  }
+//  
+//  
+//  
+//  //============================
+//  //======== addCommand ========
+//  //============================
+//  //function that adds a basic command to the queue
+//  void automatedArmchair::addCommand(commandSimple_t command) {
+//      //add command to queue
+//       if ( xQueueSend( commandQueue, ( void * )&command, ( TickType_t ) 0 ) ){
+//           ESP_LOGI(TAG, "Successfully inserted command to queue");
+//       } else {
+//           ESP_LOGE(TAG, "Failed to insert new command to queue");
+//       }
+//  }
+//  
+//  void automatedArmchair::addCommands(commandSimple_t commands[], size_t count) {
+//      for (int i = 0; i < count; i++) {
+//           ESP_LOGI(TAG, "Reading command no. %d from provided array", i);
+//          addCommand(commands[i]);
+//      }
+//  }
+//  
+//  
+//  //===============================
+//  //======== clearCommands ========
+//  //===============================
+//  //function that deletes all pending/queued commands
+//  //e.g. when switching modes
+//  motorCommands_t automatedArmchair::clearCommands() {
+//      //clear command queue
+//      xQueueReset( commandQueue );
+//      ESP_LOGW(TAG, "command queue was successfully emptied");
+//      //return commands for idling both motors
+//      motorCommands = motorCmds_bothMotorsIdle;
+//      return motorCmds_bothMotorsIdle;
+//  }
+//  
diff --git a/main/auto.hpp b/board_control/main/auto.hpp
similarity index 99%
rename from main/auto.hpp
rename to board_control/main/auto.hpp
index 8b799fb..798ecdb 100644
--- a/main/auto.hpp
+++ b/board_control/main/auto.hpp
@@ -10,7 +10,7 @@ extern "C"
 
 #include "freertos/queue.h"
 #include <cmath>
-#include "motorctl.hpp"
+#include "types.hpp"
 
 
 
diff --git a/board_control/main/button.cpp b/board_control/main/button.cpp
new file mode 100644
index 0000000..5ad9b59
--- /dev/null
+++ b/board_control/main/button.cpp
@@ -0,0 +1,222 @@
+#include "auto.hpp"
+extern "C"
+{
+#include <stdio.h>
+#include <esp_system.h>
+#include <esp_event.h>
+#include "freertos/FreeRTOS.h"
+#include "esp_log.h"
+}
+
+#include "button.hpp"
+
+
+
+//tag for logging
+static const char * TAG = "button";
+
+
+
+//FIXME needs rework, motorleft/right objectn not available anymore
+  //-----------------------------
+  //-------- constructor --------
+  //-----------------------------
+buttonCommands::buttonCommands(
+		gpio_evaluatedSwitch * button_f,
+		evaluatedJoystick * joystick_f,
+		controlledArmchair * control_f,
+		buzzer_t * buzzer_f
+		){
+      //copy object pointers
+      button = button_f;
+      joystick = joystick_f;
+      control = control_f;
+      buzzer = buzzer_f;
+      //TODO declare / configure evaluatedSwitch here instead of config (unnecessary that button object is globally available - only used here)?
+  }
+  
+  
+  
+  //----------------------------
+  //--------- action -----------
+  //----------------------------
+  //function that runs commands depending on a count value
+  void buttonCommands::action (uint8_t count, bool lastPressLong){
+      //--- variable declarations ---
+      bool decelEnabled; //for different beeping when toggling
+      commandSimple_t cmds[8]; //array for commands for automatedArmchair
+  
+      //--- get joystick position ---
+      //joystickData_t stickData = joystick->getData();
+  
+      //--- actions based on count ---
+      switch (count){
+          //no such command
+          default:
+              ESP_LOGE(TAG, "no command for count=%d defined", count);
+              buzzer->beep(3, 400, 100);
+              break;
+  
+          case 1:
+              //restart contoller when 1x long pressed
+              if (lastPressLong){
+                  ESP_LOGW(TAG, "RESTART");
+                  buzzer->beep(1,1000,1);
+                  vTaskDelay(1000 / portTICK_PERIOD_MS);
+                  esp_restart();
+                  return;
+              } 
+  
+              ESP_LOGW(TAG, "cmd %d: sending button event to control task", count);
+              //-> define joystick center or toggle freeze input (executed in control task)
+              control->sendButtonEvent(count); //TODO: always send button event to control task (not just at count=1) -> control.cpp has to be changed
+              break;
+          case 2:
+			  //TODO no use for leg support from 1.0 anymore, add other functionality
+              //run automatic commands to lift leg support when pressed 1x short 1x long
+              //if (lastPressLong){
+              //    //define commands
+              //    cmds[0] =
+              //    {
+              //        .motorCmds = {
+              //            .left = {motorstate_t::REV, 90},
+              //            .right = {motorstate_t::REV, 90}
+              //        },
+              //        .msDuration = 1200,
+              //        .fadeDecel = 800,
+              //        .fadeAccel = 1300,
+              //        .instruction = auto_instruction_t::NONE
+              //    };
+              //    cmds[1] =
+              //    {
+              //        .motorCmds = {
+              //            .left = {motorstate_t::FWD, 70},
+              //            .right = {motorstate_t::FWD, 70}
+              //        },
+              //        .msDuration = 70,
+              //        .fadeDecel = 0,
+              //        .fadeAccel = 300,
+              //        .instruction = auto_instruction_t::NONE
+              //    };
+              //    cmds[2] =
+              //    {
+              //        .motorCmds = {
+              //            .left = {motorstate_t::IDLE, 0},
+              //            .right = {motorstate_t::IDLE, 0}
+              //        },
+              //        .msDuration = 10,
+              //        .fadeDecel = 800,
+              //        .fadeAccel = 1300,
+              //        .instruction = auto_instruction_t::SWITCH_JOYSTICK_MODE
+              //    };
+  
+              //    //send commands to automatedArmchair command queue
+              //    armchair.addCommands(cmds, 3);
+  
+              //    //change mode to AUTO
+              //    control->changeMode(controlMode_t::AUTO);
+              //    return;
+              //}
+  
+              //toggle idle when 2x pressed
+              ESP_LOGW(TAG, "cmd %d: toggle IDLE", count);
+              control->toggleIdle(); //toggle between idle and previous/default mode
+              break;
+  
+  
+          case 3:
+              ESP_LOGW(TAG, "cmd %d: switch to JOYSTICK", count);
+              control->changeMode(controlMode_t::JOYSTICK); //switch to JOYSTICK mode
+              break;
+  
+          case 4:
+              ESP_LOGW(TAG, "cmd %d: toggle between HTTP and JOYSTICK", count);
+              control->toggleModes(controlMode_t::HTTP, controlMode_t::JOYSTICK); //toggle between HTTP and JOYSTICK mode
+              break;
+  
+          case 6:
+              ESP_LOGW(TAG, "cmd %d: toggle between MASSAGE and JOYSTICK", count);
+              control->toggleModes(controlMode_t::MASSAGE, controlMode_t::JOYSTICK); //toggle between MASSAGE and JOYSTICK mode
+              break;
+  
+         // case 8:
+		 //     //TODO rework this with uart config
+         //     //toggle deceleration fading between on and off
+         //     decelEnabled = motorLeft->toggleFade(fadeType_t::DECEL);
+         //     motorRight->toggleFade(fadeType_t::DECEL);
+         //     ESP_LOGW(TAG, "cmd %d: toggle deceleration fading to: %d", count, (int)decelEnabled);
+         //     if (decelEnabled){
+         //         buzzer->beep(3, 60, 50);
+         //     } else {
+         //         buzzer->beep(1, 1000, 1);
+         //     }
+              break;
+  
+          case 12:
+              ESP_LOGW(TAG, "cmd %d: sending button event to control task", count);
+              //-> toggle altStickMapping (executed in control task)
+              control->sendButtonEvent(count); //TODO: always send button event to control task (not just at count=1)?
+              break;
+  
+      }
+  }
+  
+  
+  
+  
+  //-----------------------------
+  //------ startHandleLoop ------
+  //-----------------------------
+  //this function has to be started once in a separate task
+  //repeatedly evaluates and processes button events then takes the corresponding action
+  void buttonCommands::startHandleLoop() {
+  
+      while(1) {
+          vTaskDelay(20 / portTICK_PERIOD_MS);
+          //run handle function of evaluatedSwitch object
+          button->handle();
+  
+          //--- count button presses and run action ---
+          switch(state) {
+              case inputState_t::IDLE: //wait for initial button press
+                  if (button->risingEdge) {
+                      count = 1;
+                      buzzer->beep(1, 65, 0);
+                      timestamp_lastAction = esp_log_timestamp();
+                      state = inputState_t::WAIT_FOR_INPUT;
+                      ESP_LOGI(TAG, "first button press detected -> waiting for further events");
+                  }
+                  break;
+  
+              case inputState_t::WAIT_FOR_INPUT: //wait for further presses
+                  //button pressed again
+                  if (button->risingEdge){
+                      count++;
+                      buzzer->beep(1, 65, 0);
+                      timestamp_lastAction = esp_log_timestamp();
+                      ESP_LOGI(TAG, "another press detected -> count=%d -> waiting for further events", count);
+                  }
+                  //timeout
+                  else if (esp_log_timestamp() - timestamp_lastAction > 1000) {
+                      state = inputState_t::IDLE;
+                      buzzer->beep(count, 50, 50);
+                      //TODO: add optional "bool wait" parameter to beep function to delay until finished beeping
+                      ESP_LOGI(TAG, "timeout - running action function for count=%d", count);
+                      //--- run action function ---
+                      //check if still pressed
+                      bool lastPressLong = false;
+                      if (button->state == true){
+                          //run special case when last press was longer than timeout
+                          lastPressLong = true;
+                      }
+                          //run action function with current count of button presses
+                          action(count, lastPressLong);
+                      }
+                  break;
+          }
+      }
+  }
+  
+  
+  
+  
diff --git a/board_control/main/button.hpp b/board_control/main/button.hpp
new file mode 100644
index 0000000..495f1dd
--- /dev/null
+++ b/board_control/main/button.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "gpio_evaluateSwitch.hpp"
+#include "buzzer.hpp"
+#include "control.hpp"
+#include "auto.hpp"
+#include "config.hpp"
+#include "joystick.hpp"
+#include "types.hpp"
+
+
+
+
+//===================================
+//====== buttonCommands class =======
+//===================================
+//class which runs commands depending on the count a button was pressed
+class buttonCommands {
+	public:
+		//--- constructor ---
+		buttonCommands (
+				gpio_evaluatedSwitch * button_f,
+				evaluatedJoystick * joystick_f,
+				controlledArmchair * control_f,
+				buzzer_t * buzzer_f
+				); 
+
+		//--- functions ---
+		//the following function has to be started once in a separate task. 
+		//repeatedly evaluates and processes button events then takes the corresponding action
+		void startHandleLoop(); 
+
+	private:
+		//--- functions ---
+		void action(uint8_t count, bool lastPressLong);
+
+		//--- objects ---
+		gpio_evaluatedSwitch* button;
+		evaluatedJoystick* joystick;
+		controlledArmchair * control;
+		buzzer_t* buzzer;
+
+		//--- variables ---
+		uint8_t count = 0;
+		uint32_t timestamp_lastAction = 0;
+		enum class inputState_t {IDLE, WAIT_FOR_INPUT};
+		inputState_t state = inputState_t::IDLE;
+
+};
+
diff --git a/main/config.cpp b/board_control/main/config.cpp
similarity index 53%
rename from main/config.cpp
rename to board_control/main/config.cpp
index 36593f1..876fe14 100644
--- a/main/config.cpp
+++ b/board_control/main/config.cpp
@@ -1,60 +1,5 @@
 #include "config.hpp"
 
-//===================================
-//======= motor configuration =======
-//===================================
-//--- configure left motor (hardware) ---
-single100a_config_t configDriverLeft = {
-    .gpio_pwm = GPIO_NUM_26,
-    .gpio_a = GPIO_NUM_16,
-    .gpio_b = GPIO_NUM_4,
-    .ledc_timer = LEDC_TIMER_0,
-    .ledc_channel = LEDC_CHANNEL_0,
-	.aEnabledPinState = false, //-> pins inverted (mosfets)
-	.bEnabledPinState = false,
-    .resolution = LEDC_TIMER_11_BIT,
-    .pwmFreq = 10000
-};
-
-//--- configure right motor (hardware) ---
-single100a_config_t configDriverRight = {
-    .gpio_pwm = GPIO_NUM_27,
-    .gpio_a = GPIO_NUM_2,
-    .gpio_b = GPIO_NUM_14,
-    .ledc_timer = LEDC_TIMER_1,
-    .ledc_channel = LEDC_CHANNEL_1,
-	.aEnabledPinState = false, //-> pin inverted (mosfet)
-	.bEnabledPinState = true,  //-> not inverted (direct)
-    .resolution = LEDC_TIMER_11_BIT,
-    .pwmFreq = 10000
-};
-
-
-//TODO add motor name string -> then use as log tag?
-//--- configure left motor (contol) ---
-motorctl_config_t configMotorControlLeft = {
-    .msFadeAccel = 1900, //acceleration of the motor (ms it takes from 0% to 100%)
-    .msFadeDecel = 1000, //deceleration of the motor (ms it takes from 100% to 0%)
-	.currentLimitEnabled = true,
-	.currentSensor_adc =  ADC1_CHANNEL_6, //GPIO34
-	.currentSensor_ratedCurrent = 50,
-    .currentMax = 30,
-	.deadTimeMs = 900 //minimum time motor is off between direction change
-};
-
-//--- configure right motor (contol) ---
-motorctl_config_t configMotorControlRight = {
-    .msFadeAccel = 1900, //acceleration of the motor (ms it takes from 0% to 100%)
-    .msFadeDecel = 1000, //deceleration of the motor (ms it takes from 100% to 0%)
-	.currentLimitEnabled = true,
-	.currentSensor_adc =  ADC1_CHANNEL_4, //GPIO32
-	.currentSensor_ratedCurrent = 50,
-    .currentMax = 30,
-	.deadTimeMs = 900 //minimum time motor is off between direction change
-};
-
-
-
 //==============================
 //======= control config =======
 //==============================
@@ -107,29 +52,12 @@ joystick_config_t configJoystick = {
 
 
 
-//============================
-//=== configure fan contol ===
-//============================
-fan_config_t configCooling = {
-    .gpio_fan = GPIO_NUM_13,
-    .dutyThreshold = 40,
-	.minOnMs = 1500,
-	.minOffMs = 3000,
-	.turnOffDelayMs = 5000,
-};
-
-
-
 
 //=================================
 //===== create global objects =====
 //=================================
 //TODO outsource global variables to e.g. global.cpp and only config options here?
 
-//create controlled motor instances (motorctl.hpp)
-controlledMotor motorLeft(configDriverLeft, configMotorControlLeft);
-controlledMotor motorRight(configDriverRight, configMotorControlRight);
-
 //create global joystic instance (joystick.hpp)
 evaluatedJoystick joystick(configJoystick);
 
@@ -143,7 +71,7 @@ buzzer_t buzzer(GPIO_NUM_12, 100);
 httpJoystick httpJoystickMain(configHttpJoystickMain);
 
 //create global control object (control.hpp)
-controlledArmchair control(configControl, &buzzer, &motorLeft, &motorRight, &joystick, &httpJoystickMain);
+controlledArmchair control(configControl, &buzzer, &joystick, &httpJoystickMain);
 
 //create global automatedArmchair object (for auto-mode) (auto.hpp)
 automatedArmchair armchair;
diff --git a/main/config.hpp b/board_control/main/config.hpp
similarity index 76%
rename from main/config.hpp
rename to board_control/main/config.hpp
index 2ea0b24..d0e2edd 100644
--- a/main/config.hpp
+++ b/board_control/main/config.hpp
@@ -1,13 +1,10 @@
 #pragma once
 
-#include "motordrivers.hpp"
-#include "motorctl.hpp"
 #include "joystick.hpp"
 
 #include "gpio_evaluateSwitch.hpp"
 #include "buzzer.hpp"
 #include "control.hpp"
-#include "fan.hpp"
 #include "http.hpp"
 #include "auto.hpp"
 
@@ -19,10 +16,6 @@
 
 //TODO outsource global variables to e.g. global.cpp and only config options here?
 
-//create global controlledMotor instances for both motors
-extern controlledMotor motorLeft;
-extern controlledMotor motorRight;
-
 //create global joystic instance
 extern evaluatedJoystick joystick;
 
@@ -40,7 +33,3 @@ extern automatedArmchair armchair;
 
 //create global httpJoystick object
 extern httpJoystick httpJoystickMain;
-
-//configuration for fans / cooling
-extern fan_config_t configCooling;
-
diff --git a/board_control/main/control.cpp b/board_control/main/control.cpp
new file mode 100644
index 0000000..031dace
--- /dev/null
+++ b/board_control/main/control.cpp
@@ -0,0 +1,473 @@
+#include "types.hpp"
+extern "C"
+{
+#include <stdio.h>
+#include "freertos/FreeRTOS.h"
+#include "esp_log.h"
+#include "freertos/queue.h"
+
+//custom C libraries
+#include "wifi.h"
+}
+
+#include "config.hpp"
+#include "control.hpp"
+#include "uart.hpp"
+
+
+//used definitions moved from config.hpp:
+//#define JOYSTICK_TEST
+
+
+//tag for logging
+static const char * TAG = "control";
+const char* controlModeStr[7] = {"IDLE", "JOYSTICK", "MASSAGE", "HTTP", "MQTT", "BLUETOOTH", "AUTO"};
+
+
+//FIXME controlledMotor class not available for this pcb, rework
+  //-----------------------------
+  //-------- constructor --------
+  //-----------------------------
+  controlledArmchair::controlledArmchair (
+          control_config_t config_f,
+          buzzer_t * buzzer_f,
+          evaluatedJoystick* joystick_f,
+          httpJoystick* httpJoystick_f
+          ){
+  
+      //copy configuration
+      config = config_f;
+      //copy object pointers
+      buzzer = buzzer_f;
+      joystick_l = joystick_f,
+      httpJoystickMain_l = httpJoystick_f;
+      //set default mode from config
+      modePrevious = config.defaultMode;
+      
+      //TODO declare / configure controlled motors here instead of config (unnecessary that button object is globally available - only used here)?
+  }
+  
+  
+  
+  //----------------------------------
+  //---------- Handle loop -----------
+  //----------------------------------
+  //function that repeatedly generates motor commands depending on the current mode
+  //also handles fading and current-limit
+  void controlledArmchair::startHandleLoop() {
+      while (1){
+          ESP_LOGV(TAG, "control task executing... mode=%s", controlModeStr[(int)mode]);
+  
+          switch(mode) {
+              default:
+                  mode = controlMode_t::IDLE;
+                  break;
+  
+              case controlMode_t::IDLE:
+				  //send both motors idle command to motorctl pcb
+				  uart_sendStruct<motorCommands_t>(cmds_bothMotorsIdle);
+				  commands_now = cmds_bothMotorsIdle;
+                  vTaskDelay(200 / portTICK_PERIOD_MS);
+  #ifdef JOYSTICK_LOG_IN_IDLE
+  				//get joystick data here (without using it)
+  				//since loglevel is DEBUG, calculateion details is output
+                  joystick_l->getData(); //get joystick data here
+  #endif
+                  break;
+  
+  
+              case controlMode_t::JOYSTICK:
+                  vTaskDelay(50 / portTICK_PERIOD_MS);
+                  //get current joystick data with getData method of evaluatedJoystick
+                  stickData = joystick_l->getData();
+                  //additionaly scale coordinates (more detail in slower area)
+                  joystick_scaleCoordinatesLinear(&stickData, 0.6, 0.35); //TODO: add scaling parameters to config
+                  //generate motor commands
+                  commands_now = joystick_generateCommandsDriving(stickData, altStickMapping);
+                  //apply motor commands
+				  uart_sendStruct<motorCommands_t>(commands_now);
+                  break;
+  
+  
+              case controlMode_t::MASSAGE:
+                  vTaskDelay(10 / portTICK_PERIOD_MS);
+                  //--- read joystick ---
+                  //only update joystick data when input not frozen
+                  if (!freezeInput){
+                      stickData = joystick_l->getData();
+                  }
+                  //--- generate motor commands ---
+                  //pass joystick data from getData method of evaluatedJoystick to generateCommandsShaking function
+                  commands_now = joystick_generateCommandsShaking(stickData);
+                  //apply motor commands
+				  uart_sendStruct<motorCommands_t>(commands_now);
+                  break;
+  
+  
+              case controlMode_t::HTTP:
+                  //--- get joystick data from queue ---
+                  //Note this function waits several seconds (httpconfig.timeoutMs) for data to arrive, otherwise Center data or NULL is returned
+                  //TODO: as described above, when changing modes it might delay a few seconds for the change to apply
+                  stickData = httpJoystickMain_l->getData();
+                  //scale coordinates additionally (more detail in slower area)
+                  joystick_scaleCoordinatesLinear(&stickData, 0.6, 0.4); //TODO: add scaling parameters to config
+                  ESP_LOGD(TAG, "generating commands from x=%.3f  y=%.3f  radius=%.3f  angle=%.3f", stickData.x, stickData.y, stickData.radius, stickData.angle);
+                  //--- generate motor commands ---
+                  //Note: timeout (no data received) is handled in getData method
+                  commands_now = joystick_generateCommandsDriving(stickData, altStickMapping);
+  
+                  //--- apply commands to motors ---
+				  uart_sendStruct<motorCommands_t>(commands_now);
+                 break;
+  
+  
+              case controlMode_t::AUTO:
+				 //FIXME auto mode currently not supported, needs rework
+                  vTaskDelay(20 / portTICK_PERIOD_MS);
+//                 //generate commands
+//                 commands_now = armchair.generateCommands(&instruction);
+//                  //--- apply commands to motors ---
+//                  //TODO make motorctl.setTarget also accept motorcommand struct directly
+//				  uart_sendStruct<motorCommands_t>(commands_now);
+//                 //motorRight->setTarget(commands_now.right.state, commands_now.right.duty); 
+//                 //motorLeft->setTarget(commands_now.left.state, commands_now.left.duty); 
+//  
+//                 //process received instruction
+//                 switch (instruction) {
+//                     case auto_instruction_t::NONE:
+//                         break;
+//                     case auto_instruction_t::SWITCH_PREV_MODE:
+//                         toggleMode(controlMode_t::AUTO);
+//                         break;
+//                     case auto_instruction_t::SWITCH_JOYSTICK_MODE:
+//                         changeMode(controlMode_t::JOYSTICK);
+//                         break;
+//                     case auto_instruction_t::RESET_ACCEL_DECEL:
+////                         //enable downfading (set to default value)
+////                         motorLeft->setFade(fadeType_t::DECEL, true);
+////                         motorRight->setFade(fadeType_t::DECEL, true);
+////                         //set upfading to default value
+////                         motorLeft->setFade(fadeType_t::ACCEL, true);
+////                         motorRight->setFade(fadeType_t::ACCEL, true);
+////                         break;
+//                     case auto_instruction_t::RESET_ACCEL:
+////                         //set upfading to default value
+////                         motorLeft->setFade(fadeType_t::ACCEL, true);
+////                         motorRight->setFade(fadeType_t::ACCEL, true);
+////                         break;
+//                     case auto_instruction_t::RESET_DECEL:
+////                         //enable downfading (set to default value)
+////                         motorLeft->setFade(fadeType_t::DECEL, true);
+////                         motorRight->setFade(fadeType_t::DECEL, true);
+//                         break;
+//                 }
+                 break;
+  
+                //TODO: add other modes here
+          }
+  
+  
+          //--- run actions based on received button button event ---
+  		//note: buttonCount received by sendButtonEvent method called from button.cpp
+          //TODO: what if variable gets set from other task during this code? -> mutex around this code
+		  //TODO add methods and move below code to button file possible?
+          switch (buttonCount) {
+              case 1: //define joystick center or freeze input
+                  if (mode == controlMode_t::JOYSTICK){
+                      //joystick mode: calibrate joystick
+                      joystick_l->defineCenter();
+					  buzzer->beep(2, 50, 30);
+					  buzzer->beep(1, 200, 25);
+                  } else if (mode == controlMode_t::MASSAGE){
+                      //massage mode: toggle freeze of input (lock joystick at current values)
+                      freezeInput = !freezeInput;
+                      if (freezeInput){
+                          buzzer->beep(5, 40, 25);
+                      } else {
+                          buzzer->beep(1, 300, 100);
+                      }
+                  }
+                  break;
+  
+              case 12: //toggle alternative joystick mapping (reverse swapped) 
+                  altStickMapping = !altStickMapping;
+                  if (altStickMapping){
+                      buzzer->beep(6, 70, 50);
+                  } else {
+                      buzzer->beep(1, 500, 100);
+                  }
+                  break;
+          }
+          //--- reset button event --- (only one action per run)
+          if (buttonCount > 0){
+              ESP_LOGI(TAG, "resetting button event/count");
+              buttonCount = 0;
+          }
+  
+  
+  
+          //-----------------------
+          //------ slow loop ------
+          //-----------------------
+          //this section is run about every 5s (+500ms)
+          if (esp_log_timestamp() - timestamp_SlowLoopLastRun > 5000) {
+              ESP_LOGV(TAG, "running slow loop... time since last run: %.1fs", (float)(esp_log_timestamp() - timestamp_SlowLoopLastRun)/1000);
+              timestamp_SlowLoopLastRun = esp_log_timestamp();
+  
+              //run function which detects timeout (switch to idle)
+              handleTimeout();
+          }
+  
+      }//end while(1)
+  }//end startHandleLoop
+  
+  
+  
+  //-----------------------------------
+  //---------- resetTimeout -----------
+  //-----------------------------------
+  void controlledArmchair::resetTimeout(){
+      //TODO mutex
+      timestamp_lastActivity = esp_log_timestamp();
+  }
+  
+  
+  
+  //------------------------------------
+  //--------- sendButtonEvent ----------
+  //------------------------------------
+  void controlledArmchair::sendButtonEvent(uint8_t count){
+      //TODO mutex - if not replaced with queue
+      ESP_LOGI(TAG, "setting button event");
+      buttonCount = count;
+  }
+  
+  
+  
+  //------------------------------------
+  //---------- handleTimeout -----------
+  //------------------------------------
+  //percentage the duty can vary since last timeout check and still counts as incative 
+  //TODO: add this to config
+  float inactivityTolerance = 10; 
+  
+  //local function that checks whether two values differ more than a given tolerance
+  bool validateActivity(float dutyOld, float dutyNow, float tolerance){
+      float dutyDelta = dutyNow - dutyOld;
+      if (fabs(dutyDelta) < tolerance) {
+          return false; //no significant activity detected
+      } else {
+          return true; //there was activity
+      }
+  }
+  
+  //function that evaluates whether there is no activity/change on the motor duty for a certain time. If so, a switch to IDLE is issued.
+  //has to be run repeatedly in a *slow interval* so change between current and last duty is detectable
+  void controlledArmchair::handleTimeout(){
+      //check for timeout only when not idling already
+      if (mode != controlMode_t::IDLE) {
+		  //activity detected between current and last generated motor commands
+		  if (validateActivity(commands_lastActivityCheck.left.duty, commands_now.left.duty, inactivityTolerance) 
+				  || validateActivity(commands_lastActivityCheck.right.duty, commands_now.right.duty, inactivityTolerance)
+					 ){
+              ESP_LOGD(TAG, "timeout check: [activity] detected since last check -> reset");
+              //reset last commands and timestamp
+			  commands_lastActivityCheck = commands_now;
+              resetTimeout();
+          }
+          //no activity on any motor and msTimeout exceeded
+          else if (esp_log_timestamp() - timestamp_lastActivity > config.timeoutMs){
+              ESP_LOGW(TAG, "timeout check: [TIMEOUT], no activity for more than %.ds  -> switch to idle", config.timeoutMs/1000);
+              //toggle to idle mode
+              toggleIdle();
+          }
+          else {
+              ESP_LOGD(TAG, "timeout check: [inactive], last activity %.1f s ago, timeout after %d s", (float)(esp_log_timestamp() - timestamp_lastActivity)/1000, config.timeoutMs/1000);
+          }
+      }
+  }
+  
+  
+  
+  //-----------------------------------
+  //----------- changeMode ------------
+  //-----------------------------------
+  //function to change to a specified control mode
+  //FIXME FIXME: replace change with motorLeft object with update config via uart
+  void controlledArmchair::changeMode(controlMode_t modeNew) {
+      //reset timeout timer
+      resetTimeout();
+  
+      //exit if target mode is already active
+      if (mode == modeNew) {
+          ESP_LOGE(TAG, "changeMode: Already in target mode '%s' -> nothing to change", controlModeStr[(int)mode]);
+          return;
+      }
+  
+      //copy previous mode
+      modePrevious = mode;
+  
+  	ESP_LOGW(TAG, "=== changing mode from %s to %s ===", controlModeStr[(int)mode], controlModeStr[(int)modeNew]);
+  
+  	//========== commands change FROM mode ==========
+  	//run functions when changing FROM certain mode
+  	switch(modePrevious){
+  		default:
+  			ESP_LOGI(TAG, "noting to execute when changing FROM this mode");
+  			break;
+  
+  #ifdef JOYSTICK_LOG_IN_IDLE
+  		case controlMode_t::IDLE:
+  			ESP_LOGI(TAG, "disabling debug output for 'evaluatedJoystick'");
+  			esp_log_level_set("evaluatedJoystick", ESP_LOG_WARN); //FIXME: loglevel from config
+  			break;
+  #endif
+  
+  		case controlMode_t::HTTP:
+  			ESP_LOGW(TAG, "switching from http mode -> disabling http and wifi");
+  			//stop http server
+  			ESP_LOGI(TAG, "disabling http server...");
+  			http_stop_server();
+  
+  			//FIXME: make wifi function work here - currently starting wifi at startup (see notes main.cpp)
+              //stop wifi
+              //TODO: decide whether ap or client is currently used - which has to be disabled?
+              //ESP_LOGI(TAG, "deinit wifi...");
+              //wifi_deinit_client();
+              //wifi_deinit_ap();
+              ESP_LOGI(TAG, "done stopping http mode");
+              break;
+  
+//          case controlMode_t::MASSAGE:
+//              ESP_LOGW(TAG, "switching from MASSAGE mode -> restoring fading, reset frozen input");
+//              //TODO: fix issue when downfading was disabled before switching to massage mode - currently it gets enabled again here...
+//              //enable downfading (set to default value)
+//              motorLeft->setFade(fadeType_t::DECEL, true);
+//              motorRight->setFade(fadeType_t::DECEL, true);
+//              //set upfading to default value
+//              motorLeft->setFade(fadeType_t::ACCEL, true);
+//              motorRight->setFade(fadeType_t::ACCEL, true);
+//              //reset frozen input state
+//              freezeInput = false;
+//              break;
+//  
+//          case controlMode_t::AUTO:
+//              ESP_LOGW(TAG, "switching from AUTO mode -> restoring fading to default");
+//              //TODO: fix issue when downfading was disabled before switching to auto mode - currently it gets enabled again here...
+//              //enable downfading (set to default value)
+//              motorLeft->setFade(fadeType_t::DECEL, true);
+//              motorRight->setFade(fadeType_t::DECEL, true);
+//              //set upfading to default value
+//              motorLeft->setFade(fadeType_t::ACCEL, true);
+//              motorRight->setFade(fadeType_t::ACCEL, true);
+//              break;
+      }
+  
+  
+      //========== commands change TO mode ==========
+      //run functions when changing TO certain mode
+      switch(modeNew){
+          default:
+              ESP_LOGI(TAG, "noting to execute when changing TO this mode");
+              break;
+  
+  		case controlMode_t::IDLE:
+  			buzzer->beep(1, 1500, 0);
+  #ifdef JOYSTICK_LOG_IN_IDLE
+  			esp_log_level_set("evaluatedJoystick", ESP_LOG_DEBUG);
+  #endif
+  			break;
+  
+          case controlMode_t::HTTP:
+              ESP_LOGW(TAG, "switching to http mode -> enabling http and wifi");
+              //start wifi
+              //TODO: decide wether ap or client should be started
+              ESP_LOGI(TAG, "init wifi...");
+  
+              //FIXME: make wifi function work here - currently starting wifi at startup (see notes main.cpp)
+              //wifi_init_client();
+              //wifi_init_ap();
+  
+              //wait for wifi
+              //ESP_LOGI(TAG, "waiting for wifi...");
+              //vTaskDelay(1000 / portTICK_PERIOD_MS);
+  
+              //start http server
+              ESP_LOGI(TAG, "init http server...");
+              http_init_server();
+              ESP_LOGI(TAG, "done initializing http mode");
+              break;
+  
+//          case controlMode_t::MASSAGE:
+//              ESP_LOGW(TAG, "switching to MASSAGE mode -> reducing fading");
+//              uint32_t shake_msFadeAccel = 500; //TODO: move this to config
+//  
+//              //disable downfading (max. deceleration)
+//              motorLeft->setFade(fadeType_t::DECEL, false);
+//              motorRight->setFade(fadeType_t::DECEL, false);
+//              //reduce upfading (increase acceleration)
+//              motorLeft->setFade(fadeType_t::ACCEL, shake_msFadeAccel);
+//              motorRight->setFade(fadeType_t::ACCEL, shake_msFadeAccel);
+//              break;
+  
+      }
+  
+      //--- update mode to new mode ---
+      //TODO: add mutex
+      mode = modeNew;
+  }
+  
+  
+  //TODO simplify the following 3 functions? can be replaced by one?
+  
+  //-----------------------------------
+  //----------- toggleIdle ------------
+  //-----------------------------------
+  //function to toggle between IDLE and previous active mode
+  void controlledArmchair::toggleIdle() {
+      //toggle between IDLE and previous mode
+      toggleMode(controlMode_t::IDLE);
+  }
+  
+  
+  
+  //------------------------------------
+  //----------- toggleModes ------------
+  //------------------------------------
+  //function to toggle between two modes, but prefer first argument if entirely different mode is currently active
+  void controlledArmchair::toggleModes(controlMode_t modePrimary, controlMode_t modeSecondary) {
+      //switch to secondary mode when primary is already active
+      if (mode == modePrimary){
+          ESP_LOGW(TAG, "toggleModes: switching from primaryMode %s to secondarMode %s", controlModeStr[(int)mode], controlModeStr[(int)modeSecondary]);
+          buzzer->beep(2,200,100);
+          changeMode(modeSecondary); //switch to secondary mode
+      } 
+      //switch to primary mode when any other mode is active
+      else {
+          ESP_LOGW(TAG, "toggleModes: switching from %s to primary mode %s", controlModeStr[(int)mode], controlModeStr[(int)modePrimary]);
+          buzzer->beep(4,200,100);
+          changeMode(modePrimary);
+      }
+  }
+  
+  
+  
+  //-----------------------------------
+  //----------- toggleMode ------------
+  //-----------------------------------
+  //function that toggles between certain mode and previous mode
+  void controlledArmchair::toggleMode(controlMode_t modePrimary){
+  
+      //switch to previous mode when primary is already active
+      if (mode == modePrimary){
+          ESP_LOGW(TAG, "toggleMode: switching from primaryMode %s to previousMode %s", controlModeStr[(int)mode], controlModeStr[(int)modePrevious]);
+          //buzzer->beep(2,200,100);
+          changeMode(modePrevious); //switch to previous mode
+      } 
+      //switch to primary mode when any other mode is active
+      else {
+          ESP_LOGW(TAG, "toggleModes: switching from %s to primary mode %s", controlModeStr[(int)mode], controlModeStr[(int)modePrimary]);
+          //buzzer->beep(4,200,100);
+          changeMode(modePrimary);
+      }
+  }
diff --git a/board_control/main/control.hpp b/board_control/main/control.hpp
new file mode 100644
index 0000000..58f3085
--- /dev/null
+++ b/board_control/main/control.hpp
@@ -0,0 +1,125 @@
+#pragma once
+
+#include "buzzer.hpp"
+#include "http.hpp"
+#include "auto.hpp"
+#include "types.hpp"
+
+
+//FIXME controlledMotor class not available for this pcb, rework
+  //--------------------------------------------
+  //---- struct, enum, variable declarations ---
+  //--------------------------------------------
+  //enum that decides how the motors get controlled
+  enum class controlMode_t {IDLE, JOYSTICK, MASSAGE, HTTP, MQTT, BLUETOOTH, AUTO};
+  //string array representing the mode enum (for printing the state as string)
+  extern const char* controlModeStr[7];
+  
+  //--- control_config_t ---
+  //struct with config parameters
+  typedef struct control_config_t {
+      controlMode_t defaultMode;  //default mode after startup and toggling IDLE
+      //timeout options
+      uint32_t timeoutMs;         //time of inactivity after which the mode gets switched to IDLE
+      float timeoutTolerancePer;  //percentage the duty can vary between timeout checks considered still inactive
+  } control_config_t;
+  
+  
+  
+  
+  //==================================
+  //========= control class ==========
+  //==================================
+  //controls the mode the armchair operates
+  //repeatedly generates the motor commands corresponding to current mode and sends those to motorcontrol
+  class controlledArmchair {
+      public:
+          //--- constructor ---
+          controlledArmchair (
+                  control_config_t config_f,
+                  buzzer_t* buzzer_f,
+                  evaluatedJoystick* joystick_f,
+                  httpJoystick* httpJoystick_f
+                  );
+  
+          //--- functions ---
+          //task that repeatedly generates motor commands depending on the current mode
+          void startHandleLoop();
+  
+          //function that changes to a specified control mode
+          void changeMode(controlMode_t modeNew);
+  
+          //function that toggle between IDLE and previous active mode (or default if not switched to certain mode yet)
+          void toggleIdle();
+  
+          //function that toggles between two modes, but prefers first argument if entirely different mode is currently active
+          void toggleModes(controlMode_t modePrimary, controlMode_t modeSecondary);
+  
+          //toggle between certain mode and previous mode
+          void toggleMode(controlMode_t modePrimary);
+  
+          //function that restarts timer which initiates the automatic timeout (switch to IDLE) after certain time of inactivity
+          void resetTimeout();
+  
+          //function for sending a button event (e.g. from button task at event) to control task
+          //TODO: use queue instead?
+          void sendButtonEvent(uint8_t count);
+  
+      private:
+  
+          //--- functions ---
+          //function that evaluates whether there is no activity/change on the motor duty for a certain time, if so a switch to IDLE is issued. - has to be run repeatedly in a slow interval
+          void handleTimeout();
+  
+          //--- objects ---
+          buzzer_t* buzzer;
+          httpJoystick* httpJoystickMain_l;
+          evaluatedJoystick* joystick_l;
+  
+          //---variables ---
+          //struct for motor commands returned by generate functions of each mode
+          motorCommands_t commands_now;
+          //struct with config parameters
+          control_config_t config;
+  
+          //store joystick data
+          joystickData_t stickData;
+          bool altStickMapping; //alternative joystick mapping (reverse mapped differently)
+  
+          //variables for http mode
+          uint32_t http_timestamp_lastData = 0;
+  
+          //variables for MASSAGE mode
+          bool freezeInput = false;
+  
+          //variables for AUTO mode
+          auto_instruction_t instruction = auto_instruction_t::NONE; //variable to receive instructions from automatedArmchair
+          
+          //variable to store button event
+          uint8_t buttonCount = 0;
+  
+          //definition of mode enum
+          controlMode_t mode = controlMode_t::IDLE;
+  
+          //variable to store mode when toggling IDLE mode 
+          controlMode_t modePrevious; //default mode
+  
+          //command preset for idling motors
+          const motorCommand_t cmd_motorIdle = {
+              .state = motorstate_t::IDLE,
+              .duty = 0
+          };
+          const motorCommands_t cmds_bothMotorsIdle = {
+              .left = cmd_motorIdle,
+              .right = cmd_motorIdle
+          };
+  
+          //variable for slow loop
+          uint32_t timestamp_SlowLoopLastRun = 0;
+  
+          //variables for detecting timeout (switch to idle, after inactivity)
+          uint32_t timestamp_lastActivity = 0;
+		  motorCommands_t commands_lastActivityCheck;
+  };
+  
+  
diff --git a/main/http.cpp b/board_control/main/http.cpp
similarity index 98%
rename from main/http.cpp
rename to board_control/main/http.cpp
index b7519c9..04844de 100644
--- a/main/http.cpp
+++ b/board_control/main/http.cpp
@@ -232,8 +232,8 @@ void http_init_server()
 
 
   //----- define URLs -----
-    //note: ignore warning here, cant define elements separately, causes crash
-  httpd_uri_t joystick_url = {
+  //note: dont use separate assignment of elements because causes controller crash
+    httpd_uri_t joystick_url = {
       .uri = "/api/joystick",
       .method = HTTP_POST,
       .handler = on_joystick_url,
diff --git a/main/http.hpp b/board_control/main/http.hpp
similarity index 100%
rename from main/http.hpp
rename to board_control/main/http.hpp
diff --git a/main/joystick.cpp b/board_control/main/joystick.cpp
similarity index 100%
rename from main/joystick.cpp
rename to board_control/main/joystick.cpp
diff --git a/main/joystick.hpp b/board_control/main/joystick.hpp
similarity index 98%
rename from main/joystick.hpp
rename to board_control/main/joystick.hpp
index dc12b15..ccf5bec 100644
--- a/main/joystick.hpp
+++ b/board_control/main/joystick.hpp
@@ -11,7 +11,7 @@ extern "C"
 }
 
 #include <cmath>
-#include "motorctl.hpp" //for declaration of motorCommands_t struct
+#include "types.hpp"
 
 
 //======================================
diff --git a/board_control/main/main.cpp b/board_control/main/main.cpp
new file mode 100644
index 0000000..260310a
--- /dev/null
+++ b/board_control/main/main.cpp
@@ -0,0 +1,243 @@
+extern "C"
+{
+#include <stdio.h>
+#include <esp_system.h>
+#include <esp_event.h>
+#include <nvs_flash.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/gpio.h"
+#include "esp_log.h"
+#include "sdkconfig.h"
+#include "esp_spiffs.h"    
+
+
+	//custom C files
+	#include "wifi.h"
+}
+
+
+#include "uart.hpp"
+
+
+//=========================
+//======= UART TEST =======
+//=========================
+//only run uart test code at the end
+//disables other functionality
+//#define UART_TEST_ONLY
+
+
+//tag for logging
+static const char * TAG = "main";
+
+
+#ifndef UART_TEST_ONLY
+//custom C++ files
+#include "config.hpp"
+#include "control.hpp" 
+#include "button.hpp"
+#include "http.hpp"
+
+
+
+//======================================
+//============ buzzer task =============
+//======================================
+//TODO: move the task creation to buzzer class (buzzer.cpp)
+//e.g. only have function buzzer.createTask() in app_main
+void task_buzzer( void * pvParameters ){
+	ESP_LOGI("task_buzzer", "Start of buzzer task...");
+	//run function that waits for a beep events to arrive in the queue
+	//and processes them
+	buzzer.processQueue();
+}
+
+
+
+//=======================================
+//============ control task =============
+//=======================================
+//task that controls the armchair modes and initiates commands generation and applies them to driver
+void task_control( void * pvParameters ){
+	ESP_LOGI(TAG, "Initializing controlledArmchair and starting handle loop");
+	//start handle loop (control object declared in config.hpp)
+	control.startHandleLoop();
+}
+
+
+
+//======================================
+//============ button task =============
+//======================================
+//task that handles the button interface/commands
+void task_button( void * pvParameters ){
+	ESP_LOGI(TAG, "Initializing command-button and starting handle loop");
+	//create button instance
+	buttonCommands commandButton(&buttonJoystick, &joystick, &control, &buzzer);
+	//start handle loop
+	commandButton.startHandleLoop();
+}
+
+
+
+//=======================================
+//============== fan task ===============
+//=======================================
+//task that controlls fans for cooling the drivers
+//void task_fans( void * pvParameters ){
+//	ESP_LOGI(TAG, "Initializing fans and starting fan handle loop");
+//	//create fan instances with config defined in config.cpp
+//	controlledFan fan(configCooling, &motorLeft, &motorRight);
+//	//repeatedly run fan handle function in a slow loop
+//	while(1){
+//		fan.handle();
+//		vTaskDelay(500 / portTICK_PERIOD_MS);
+//	}
+//}
+
+
+
+//=================================
+//========== init spiffs ==========
+//=================================
+//initialize spi flash filesystem (used for webserver)
+void init_spiffs(){
+	ESP_LOGI(TAG, "init spiffs");
+	esp_vfs_spiffs_conf_t esp_vfs_spiffs_conf = {
+		.base_path = "/spiffs",
+		.partition_label = NULL,
+		.max_files = 5,
+		.format_if_mount_failed = true};
+	esp_vfs_spiffs_register(&esp_vfs_spiffs_conf);
+
+	size_t total = 0;
+	size_t used = 0;
+	esp_spiffs_info(NULL, &total, &used);
+
+	ESP_LOGI(TAG, "SPIFFS: total %d, used %d", total, used);
+	esp_vfs_spiffs_unregister(NULL);
+}
+#endif
+
+
+
+//==================================
+//======== define loglevels ========
+//==================================
+void setLoglevels(void){
+	//set loglevel for all tags:
+	esp_log_level_set("*", ESP_LOG_WARN);
+
+	//--- set loglevel for individual tags ---
+	esp_log_level_set("main", ESP_LOG_INFO);
+	esp_log_level_set("buzzer", ESP_LOG_ERROR);
+	//esp_log_level_set("motordriver", ESP_LOG_INFO);
+	//esp_log_level_set("motor-control", ESP_LOG_DEBUG);
+	//esp_log_level_set("evaluatedJoystick", ESP_LOG_DEBUG);
+	//esp_log_level_set("joystickCommands", ESP_LOG_DEBUG);
+	esp_log_level_set("button", ESP_LOG_INFO);
+	esp_log_level_set("control", ESP_LOG_INFO);
+	esp_log_level_set("fan-control", ESP_LOG_INFO);
+	esp_log_level_set("wifi", ESP_LOG_INFO);
+	esp_log_level_set("http", ESP_LOG_INFO);
+	esp_log_level_set("automatedArmchair", ESP_LOG_DEBUG);
+	esp_log_level_set("uart-common", ESP_LOG_INFO);
+	esp_log_level_set("uart", ESP_LOG_INFO);
+
+	//
+}
+
+
+
+
+
+
+//=================================
+//=========== app_main ============
+//=================================
+extern "C" void app_main(void) {
+#ifndef UART_TEST_ONLY
+	//enable 5V volate regulator
+	gpio_pad_select_gpio(GPIO_NUM_17);                                                  
+	gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT);
+	gpio_set_level(GPIO_NUM_17, 1);                                                      
+
+	//---- define log levels ----
+	setLoglevels();
+
+	//------------------------------
+	//--- create task for buzzer ---
+	//------------------------------
+	xTaskCreate(&task_buzzer, "task_buzzer", 2048, NULL, 2, NULL);
+
+	//-------------------------------
+	//--- create task for control ---
+	//-------------------------------
+	//task that generates motor commands depending on the current mode and sends those to motorctl task
+	xTaskCreate(&task_control, "task_control", 5*4096, NULL, 5, NULL);
+
+	//------------------------------
+	//--- create task for button ---
+	//------------------------------
+	//task that evaluates and processes the button input and runs the configured commands
+	xTaskCreate(&task_button, "task_button", 4096, NULL, 4, NULL);
+
+	//-----------------------------------
+	//--- create task for fan control ---
+	//-----------------------------------
+	//task that evaluates and processes the button input and runs the configured commands
+	//xTaskCreate(&task_fans, "task_fans", 2048, NULL, 1, NULL);
+
+
+	//beep at startup
+	buzzer.beep(3, 70, 50);
+
+	//--- initialize nvs-flash and netif (needed for wifi) ---
+	wifi_initNvs_initNetif();
+
+	//--- initialize spiffs ---
+	init_spiffs();
+
+	//--- initialize and start wifi ---
+	//FIXME: run wifi_init_client or wifi_init_ap as intended from control.cpp when switching state 
+	//currently commented out because of error "assert failed: xQueueSemaphoreTake queue.c:1549 (pxQueue->uxItemSize == 0)" when calling control->changeMode from button.cpp
+	//when calling control.changeMode(http) from main.cpp it worked without error for some reason?
+	ESP_LOGI(TAG,"starting wifi...");
+	//wifi_init_client(); //connect to existing wifi
+	wifi_init_ap(); //start access point
+	ESP_LOGI(TAG,"done starting wifi");
+
+
+	//--- testing http server ---
+	//    wifi_init_client(); //connect to existing wifi
+	//    vTaskDelay(2000 / portTICK_PERIOD_MS);
+	//    ESP_LOGI(TAG, "initializing http server");
+	//    http_init_server();
+
+
+#endif
+
+	//-------------------------------------------
+	//--- create tasks for uart communication ---
+	//-------------------------------------------
+
+	uart_init();
+	xTaskCreate(task_uartReceive, "task_uartReceive", 4096, NULL, 10, NULL);
+	xTaskCreate(task_uartSend, "task_uartSend", 4096, NULL, 10, NULL);
+
+	//--- main loop ---
+	//does nothing except for testing things
+	
+	//--- testing force http mode after startup ---
+		vTaskDelay(5000 / portTICK_PERIOD_MS);
+	control.changeMode(controlMode_t::HTTP);
+	while(1){
+		vTaskDelay(1000 / portTICK_PERIOD_MS);
+		//---------------------------------
+		//-------- TESTING section --------
+		//---------------------------------
+
+	}
+
+}
diff --git a/board_control/main/uart.cpp b/board_control/main/uart.cpp
new file mode 100644
index 0000000..eaf55d6
--- /dev/null
+++ b/board_control/main/uart.cpp
@@ -0,0 +1,55 @@
+extern "C"
+{
+#include <stdio.h>
+#include <esp_system.h>
+#include <esp_event.h>
+#include <nvs_flash.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/gpio.h"
+#include "esp_log.h"
+#include "sdkconfig.h"
+#include <string.h>
+
+#include "freertos/queue.h"
+#include "driver/uart.h"
+}
+#include "uart.hpp"
+
+static const char * TAG = "uart";
+
+
+
+//==============================
+//====== task_uartReceive ======
+//==============================
+//TODO copy receive task from board_motorctl/uart.cpp
+void task_uartReceive(void *arg){
+	while (1) {
+		vTaskDelay(200 / portTICK_PERIOD_MS);
+	}
+}
+
+
+
+//=============================
+//======= task_uartSend =======
+//=============================
+//repeatedly send structs via uart
+//note: uart_sendStruct() from uart_common.hpp can be used anywhere
+void task_uartSend(void *arg){
+	static const char * TAG = "uart-send";
+	uartData_test_t data = {123, 0, 1.1};
+	ESP_LOGW(TAG, "send task started");
+	//repeatedly send data for testing uart
+	while (1) {
+		vTaskDelay(5000 / portTICK_PERIOD_MS);    
+		uart_sendStruct<uartData_test_t>(data);
+
+		//change data values
+		data.timestamp = esp_log_timestamp();
+		data.id++;
+		data.value += 0.6;
+	}
+	ESP_LOGE(TAG, "loop exit...");
+}
diff --git a/board_control/main/uart.hpp b/board_control/main/uart.hpp
new file mode 100644
index 0000000..2c8195f
--- /dev/null
+++ b/board_control/main/uart.hpp
@@ -0,0 +1,10 @@
+#pragma once
+#include "uart_common.hpp"
+
+//===== uart board CONTROL =====
+//
+void task_uartReceive(void *arg);
+void task_uartSend(void *arg);
+
+
+
diff --git a/partitions.csv b/board_control/partitions.csv
similarity index 100%
rename from partitions.csv
rename to board_control/partitions.csv
diff --git a/react-app/package-lock.json b/board_control/react-app/package-lock.json
similarity index 100%
rename from react-app/package-lock.json
rename to board_control/react-app/package-lock.json
diff --git a/react-app/package.json b/board_control/react-app/package.json
similarity index 100%
rename from react-app/package.json
rename to board_control/react-app/package.json
diff --git a/react-app/public/index.html b/board_control/react-app/public/index.html
similarity index 100%
rename from react-app/public/index.html
rename to board_control/react-app/public/index.html
diff --git a/react-app/src/App.js b/board_control/react-app/src/App.js
similarity index 100%
rename from react-app/src/App.js
rename to board_control/react-app/src/App.js
diff --git a/react-app/src/index.js b/board_control/react-app/src/index.js
similarity index 100%
rename from react-app/src/index.js
rename to board_control/react-app/src/index.js
diff --git a/CMakeLists.txt b/board_motorctl/CMakeLists.txt
similarity index 87%
rename from CMakeLists.txt
rename to board_motorctl/CMakeLists.txt
index cd14e0b..b692e77 100644
--- a/CMakeLists.txt
+++ b/board_motorctl/CMakeLists.txt
@@ -5,4 +5,5 @@
 cmake_minimum_required(VERSION 3.5)
 
 include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+set(EXTRA_COMPONENT_DIRS "../components ../common")
 project(armchair)
diff --git a/board_motorctl/README.md b/board_motorctl/README.md
new file mode 100644
index 0000000..62aefc0
--- /dev/null
+++ b/board_motorctl/README.md
@@ -0,0 +1,143 @@
+Firmware for a homemade automated electric armchair.  
+More details about this project: https://pfusch.zone/electric-armchair
+
+
+
+# Installation
+### Install esp-idf
+For this project **ESP-IDF v4.4.4** is required (with other versions it might not compile)
+```bash
+#download esp-idf
+yay -S esp-idf #alternatively clone the esp-idf repository from github
+#run installation script in installed folder
+/opt/esp-idf/install.sh
+```
+### Clone this repo
+```
+git clone git@github.com:Jonny999999/armchair_fw
+```
+### Instal node packages
+For the react app packages have to be installed with npm TODO: add this to cmake?
+```
+cd react-app
+npm install
+```
+
+
+
+# Compilation
+## react-webapp
+For the webapp to work on the esp32 it has to be built.
+When flashing, the folder react-app/build is flashed to siffs (which is used as webroot) onto the esp32.
+The following command builds the react webapp and creates this folder
+TODO: add this to flash target with cmake?
+```bash
+cd react-app
+#compile
+npm run build
+#remove unwanted license file (filename too long for spiffs)
+rm build/static/js/main.8f9aec76.js.LICENSE.txt
+```
+Note: Use `npm start` for starting the webapp locally for testing
+
+## esp project
+### Set up environment
+```bash
+source /opt/esp-idf/export.sh
+```
+(run once in terminal)
+
+### Compile
+```bash
+idf.py build
+```
+
+### Upload
+- connect FTDI programmer to board (VCC to VCC; TX to RX; RX to TX)
+- press REST and BOOT button
+- release RESET button (keep pressing boot)
+- run flash command:
+```bash
+idf.py flash
+```
+- once "connecting...' successfully, BOOT button can be released
+
+### Monitor
+- connect FTDI programmer to board (VCC to VCC; TX to RX; RX to TX)
+- press REST and BOOT button
+- release RESET button (keep pressing boot)
+- run monitor command:
+```bash
+idf.py monitor
+```
+- once connected release BOOT button
+- press RESET button once for restart
+
+
+
+# Hardware setup
+## pcb
+Used pcb developed in this project: https://pfusch.zone/project-work-2020
+
+## connection plan
+A diagram which shows what components are connected to which terminals of the pcb exists here:  
+[connection-plan.drawio.pdf](connection-plan.drawio.pdf)
+
+
+
+# Planned Features
+- More sensors:
+  - Accelerometer
+  - Lidar sensor
+  - GPS receiver
+- Anti slip regulation
+- Self driving algorithm
+- Lights
+- drinks holder
+- improved webinterface
+
+
+
+# Todo
+**Add switch functions**
+- set loglevel
+- define max-speed
+- calibrate joystick (min, max, center)
+- testing mode / dry-run
+
+
+
+# Usage
+## Switch functions
+**Currently implemented**
+| Count | Type | Action | Description |
+| --- | --- | --- | --- |
+| 1x | configure | [JOYSTICK] **calibrate stick** | when in joystick mode: set joystick center to current joystick pos |
+| 1x | control | [MASSAGE] **freeze** input | when in massage mode: lock or unlock joystick input at current position |
+| 2x | toggle mode | **IDLE** <=> previous | enable/disable chair armchair e.g. enable after startup or timeout |
+| 3x | switch mode | **JOYSTICK** | switch to default mode JOYSTICK |
+| 4x | toggle mode | **HTTP** <=> JOYSTICK | switch to '**remote control** via web-app `http://191.168.4.1`' or back to JOYSTICK mode |
+| 5x | | | |
+| 6x | toggle mode | **MASSAGE** <=> JOYSTICK | switch to MASSAGE mode or back to JOYSTICK mode |
+| 7x | | | |
+| 8x | toggle option | **deceleration limit** | disable/enable deceleration limit (default on) => more responsive |
+| | | | |
+| 12x | toggle option | **alt stick mapping** | toggle between default and alternative stick mapping (reverse swapped) |
+| >1s | system | **restart** | Restart the controller when pressing the button longer than 1 second | 
+| 1x short, 1x long | auto command | **eject** foot support | automatically go forward and reverse for certain time with no acceleration limits, so foot support ejects |
+
+
+## HTTP mode
+Control armchair via virtual joystick on a webinterface.  
+
+**Usage**
+- Connect to wifi `armchar`, no password
+- Access http://192.168.4.1  (note: **http** NOT https, some browsers automatically add https!)  
+
+**Current Features**
+- Control direction and speed with joystick  
+
+**Todo**
+- Set parameters
+- Control other modes
+- Execute preset movement commands
diff --git a/board_motorctl/main/CMakeLists.txt b/board_motorctl/main/CMakeLists.txt
new file mode 100644
index 0000000..4b2b42c
--- /dev/null
+++ b/board_motorctl/main/CMakeLists.txt
@@ -0,0 +1,12 @@
+idf_component_register(
+    SRCS 
+        "main.cpp"
+        "motordrivers.cpp"
+        "motorctl.cpp"
+        "config.cpp"
+        "fan.cpp"
+		"currentsensor.cpp"
+		"uart.cpp"
+    INCLUDE_DIRS 
+        "."
+    )
diff --git a/board_motorctl/main/config.cpp b/board_motorctl/main/config.cpp
new file mode 100644
index 0000000..3d57660
--- /dev/null
+++ b/board_motorctl/main/config.cpp
@@ -0,0 +1,85 @@
+
+#include "config.hpp"
+
+//===================================
+//======= motor configuration =======
+//===================================
+//--- configure left motor (hardware) ---
+single100a_config_t configDriverLeft = {
+    .gpio_pwm = GPIO_NUM_26,
+    .gpio_a = GPIO_NUM_4,
+    .gpio_b = GPIO_NUM_16,
+	.gpio_brakeRelay = GPIO_NUM_5, //power mosfet 2
+    .ledc_timer = LEDC_TIMER_0,
+    .ledc_channel = LEDC_CHANNEL_0,
+	.aEnabledPinState = false, //-> pins inverted (mosfets)
+	.bEnabledPinState = false,
+    .resolution = LEDC_TIMER_11_BIT,
+    .pwmFreq = 10000
+};
+
+//--- configure right motor (hardware) ---
+single100a_config_t configDriverRight = {
+    .gpio_pwm = GPIO_NUM_27,
+    .gpio_a = GPIO_NUM_2,
+    .gpio_b = GPIO_NUM_15,
+	.gpio_brakeRelay = GPIO_NUM_18, //power mosfet 1
+    .ledc_timer = LEDC_TIMER_1,
+    .ledc_channel = LEDC_CHANNEL_1,
+	.aEnabledPinState = false, //-> pins inverted (mosfets)
+	.bEnabledPinState = false,
+    .resolution = LEDC_TIMER_11_BIT,
+    .pwmFreq = 10000
+};
+
+
+//TODO add motor name string -> then use as log tag?
+//--- configure left motor (contol) ---
+motorctl_config_t configMotorControlLeft = {
+    .msFadeAccel = 1900, //acceleration of the motor (ms it takes from 0% to 100%)
+    .msFadeDecel = 1000, //deceleration of the motor (ms it takes from 100% to 0%)
+	.currentLimitEnabled = false,
+	.currentSensor_adc =  ADC1_CHANNEL_0, //GPIO36
+	.currentSensor_ratedCurrent = 50,
+    .currentMax = 30,
+	.deadTimeMs = 900 //minimum time motor is off between direction change
+};
+
+//--- configure right motor (contol) ---
+motorctl_config_t configMotorControlRight = {
+    .msFadeAccel = 1900, //acceleration of the motor (ms it takes from 0% to 100%)
+    .msFadeDecel = 1000, //deceleration of the motor (ms it takes from 100% to 0%)
+	.currentLimitEnabled = false,
+	.currentSensor_adc =  ADC1_CHANNEL_3, //GPIO39
+	.currentSensor_ratedCurrent = 50,
+    .currentMax = 30,
+	.deadTimeMs = 900 //minimum time motor is off between direction change
+};
+
+
+
+//============================
+//=== configure fan contol ===
+//============================
+fan_config_t configCooling = {
+    .gpio_fan = GPIO_NUM_13,
+    .dutyThreshold = 40,
+	.minOnMs = 1500,
+	.minOffMs = 3000,
+	.turnOffDelayMs = 5000,
+};
+
+
+
+
+//=================================
+//===== create global objects =====
+//=================================
+//TODO outsource global variables to e.g. global.cpp and only config options here?
+
+//create controlled motor instances (motorctl.hpp)
+controlledMotor motorLeft(configDriverLeft, configMotorControlLeft);
+controlledMotor motorRight(configDriverRight, configMotorControlRight);
+
+//create buzzer object on pin 12 with gap between queued events of 100ms 
+buzzer_t buzzer(GPIO_NUM_12, 100);
diff --git a/board_motorctl/main/config.hpp b/board_motorctl/main/config.hpp
new file mode 100644
index 0000000..9c4c979
--- /dev/null
+++ b/board_motorctl/main/config.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "motordrivers.hpp"
+#include "motorctl.hpp"
+
+#include "gpio_evaluateSwitch.hpp"
+#include "buzzer.hpp"
+#include "fan.hpp"
+
+
+//in IDLE mode: set loglevel for evaluatedJoystick to DEBUG 
+//and repeatedly read joystick e.g. for manually calibrating / testing joystick
+//#define JOYSTICK_LOG_IN_IDLE
+
+
+//TODO outsource global variables to e.g. global.cpp and only config options here?
+
+//create global controlledMotor instances for both motors
+extern controlledMotor motorLeft;
+extern controlledMotor motorRight;
+
+//create global buzzer object
+extern buzzer_t buzzer;
+
+//configuration for fans / cooling
+extern fan_config_t configCooling;
+
diff --git a/main/currentsensor.cpp b/board_motorctl/main/currentsensor.cpp
similarity index 100%
rename from main/currentsensor.cpp
rename to board_motorctl/main/currentsensor.cpp
diff --git a/main/currentsensor.hpp b/board_motorctl/main/currentsensor.hpp
similarity index 100%
rename from main/currentsensor.hpp
rename to board_motorctl/main/currentsensor.hpp
diff --git a/main/fan.cpp b/board_motorctl/main/fan.cpp
similarity index 100%
rename from main/fan.cpp
rename to board_motorctl/main/fan.cpp
diff --git a/main/fan.hpp b/board_motorctl/main/fan.hpp
similarity index 100%
rename from main/fan.hpp
rename to board_motorctl/main/fan.hpp
diff --git a/board_motorctl/main/main.cpp b/board_motorctl/main/main.cpp
new file mode 100644
index 0000000..4b527c3
--- /dev/null
+++ b/board_motorctl/main/main.cpp
@@ -0,0 +1,217 @@
+extern "C"
+{
+#include <stdio.h>
+#include <esp_system.h>
+#include <esp_event.h>
+#include <nvs_flash.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/gpio.h"
+#include "esp_log.h"
+#include "sdkconfig.h"
+#include "esp_spiffs.h"    
+#include <string.h>
+
+#include "driver/ledc.h"
+
+//custom C files
+#include "wifi.h"
+}
+//custom C++ files
+#include "config.hpp"
+#include "uart.hpp"
+
+//=========================
+//======= UART TEST =======
+//=========================
+//only run uart test code at the end
+//disables other functionality
+//#define UART_TEST_ONLY
+
+//==========================
+//======= BRAKE TEST =======
+//==========================
+//only run brake-test (ignore uart input)
+#define BRAKE_TEST_ONLY
+
+
+//tag for logging
+static const char * TAG = "main";
+
+
+#ifndef UART_TEST_ONLY
+//====================================
+//========== motorctl task ===========
+//====================================
+//task for handling the motors (ramp, current limit, driver)
+void task_motorctl( void * pvParameters ){
+	ESP_LOGI(TAG, "starting handle loop...");
+	while(1){
+		motorRight.handle();
+		motorLeft.handle();
+		//10khz -> T=100us
+		vTaskDelay(10 / portTICK_PERIOD_MS);
+	}
+}
+
+
+
+//======================================
+//============ buzzer task =============
+//======================================
+//TODO: move the task creation to buzzer class (buzzer.cpp)
+//e.g. only have function buzzer.createTask() in app_main
+void task_buzzer( void * pvParameters ){
+	ESP_LOGI("task_buzzer", "Start of buzzer task...");
+	//run function that waits for a beep events to arrive in the queue
+	//and processes them
+	buzzer.processQueue();
+}
+
+
+
+//=======================================
+//============== fan task ===============
+//=======================================
+//task that controlls fans for cooling the drivers
+void task_fans( void * pvParameters ){
+	ESP_LOGI(TAG, "Initializing fans and starting fan handle loop");
+	//create fan instances with config defined in config.cpp
+	controlledFan fan(configCooling, &motorLeft, &motorRight);
+	//repeatedly run fan handle function in a slow loop
+	while(1){
+		fan.handle();
+		vTaskDelay(500 / portTICK_PERIOD_MS);
+	}
+}
+
+
+
+//==================================
+//======== define loglevels ========
+//==================================
+void setLoglevels(void){
+	//set loglevel for all tags:
+	esp_log_level_set("*", ESP_LOG_WARN);
+
+	//--- set loglevel for individual tags ---
+	esp_log_level_set("main", ESP_LOG_INFO);
+	esp_log_level_set("buzzer", ESP_LOG_ERROR);
+	esp_log_level_set("motordriver", ESP_LOG_VERBOSE);
+	esp_log_level_set("motor-control", ESP_LOG_INFO);
+	//esp_log_level_set("evaluatedJoystick", ESP_LOG_DEBUG);
+	//esp_log_level_set("joystickCommands", ESP_LOG_DEBUG);
+	esp_log_level_set("button", ESP_LOG_INFO);
+	esp_log_level_set("control", ESP_LOG_INFO);
+	esp_log_level_set("fan-control", ESP_LOG_INFO);
+	esp_log_level_set("wifi", ESP_LOG_INFO);
+	esp_log_level_set("http", ESP_LOG_INFO);
+	esp_log_level_set("automatedArmchair", ESP_LOG_DEBUG);
+	esp_log_level_set("uart_common", ESP_LOG_INFO);
+	esp_log_level_set("uart", ESP_LOG_INFO);
+	//esp_log_level_set("current-sensors", ESP_LOG_INFO);
+}
+#endif
+
+
+//=================================
+//=========== app_main ============
+//=================================
+extern "C" void app_main(void) {
+#ifndef UART_TEST_ONLY
+	//enable 5V volate regulator
+	gpio_pad_select_gpio(GPIO_NUM_17);                                                  
+	gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT);
+	gpio_set_level(GPIO_NUM_17, 1);                                                      
+
+	//---- define log levels ----
+	setLoglevels();
+
+	//----------------------------------------------
+	//--- create task for controlling the motors ---
+	//----------------------------------------------
+	//task that receives commands, handles ramp and current limit and executes commands using the motordriver function
+	xTaskCreate(&task_motorctl, "task_motor-control", 2048, NULL, 6, NULL);
+
+	//------------------------------
+	//--- create task for buzzer ---
+	//------------------------------
+	xTaskCreate(&task_buzzer, "task_buzzer", 2048, NULL, 2, NULL);
+
+
+	//-----------------------------------
+	//--- create task for fan control ---
+	//-----------------------------------
+	//task that evaluates and processes the button input and runs the configured commands
+	xTaskCreate(&task_fans, "task_fans", 2048, NULL, 1, NULL);
+
+
+	//beep at startup
+	buzzer.beep(3, 70, 50);
+#endif
+
+
+
+	//-------------------------------------------
+	//--- create tasks for uart communication ---
+	//-------------------------------------------
+#ifndef BRAKE_TEST_ONLY
+	uart_init();
+	xTaskCreate(task_uartReceive, "task_uartReceive", 4096, NULL, 10, NULL);
+	xTaskCreate(task_uartSend, "task_uartSend", 4096, NULL, 10, NULL);
+#endif
+
+
+	//--- main loop ---
+	//does nothing except for testing things
+	while(1){
+		vTaskDelay(500 / portTICK_PERIOD_MS);
+#ifdef BRAKE_TEST_ONLY
+		//test relays at standstill
+		ESP_LOGW("brake-test", "test relays via motorctl");
+		//turn on
+		motorRight.setTarget(motorstate_t::BRAKE, 0);
+		vTaskDelay(500 / portTICK_PERIOD_MS);
+		motorRight.setTarget(motorstate_t::BRAKE, 0);
+		vTaskDelay(1000 / portTICK_PERIOD_MS);
+		//turn off
+		motorRight.setTarget(motorstate_t::IDLE, 0);
+		vTaskDelay(500 / portTICK_PERIOD_MS);
+		motorRight.setTarget(motorstate_t::IDLE, 0);
+
+		vTaskDelay(1000 / portTICK_PERIOD_MS);
+
+		//go forward and brake
+		ESP_LOGW("brake-test", "go forward 30%% then brake");
+		motorRight.setTarget(motorstate_t::FWD, 30);
+		vTaskDelay(1000 / portTICK_PERIOD_MS);
+		motorRight.setTarget(motorstate_t::BRAKE, 0);
+
+		vTaskDelay(3000 / portTICK_PERIOD_MS);
+
+		//brake partial
+		ESP_LOGW("brake-test", "go forward 30%% then brake partial 10%%, hold for 5sec");
+		motorRight.setTarget(motorstate_t::FWD, 30);
+		vTaskDelay(1000 / portTICK_PERIOD_MS);
+		motorRight.setTarget(motorstate_t::BRAKE, 10);
+
+		vTaskDelay(5000 / portTICK_PERIOD_MS);
+		//reset to idle
+		motorRight.setTarget(motorstate_t::IDLE, 0);
+	
+#endif
+
+
+		//--- test controlledMotor --- (ramp)
+		// //brake for 1 s
+		// motorLeft.setTarget(motorstate_t::BRAKE);
+		// vTaskDelay(1000 / portTICK_PERIOD_MS);
+		// //command 90% - reverse
+		// motorLeft.setTarget(motorstate_t::REV, 90);
+		// vTaskDelay(5000 / portTICK_PERIOD_MS);
+		// //command 100% - forward
+		// motorLeft.setTarget(motorstate_t::FWD, 100);
+		// vTaskDelay(1000 / portTICK_PERIOD_MS);
+
+	}
+}
diff --git a/main/motorctl.cpp b/board_motorctl/main/motorctl.cpp
similarity index 91%
rename from main/motorctl.cpp
rename to board_motorctl/main/motorctl.cpp
index df544ea..b560ad4 100644
--- a/main/motorctl.cpp
+++ b/board_motorctl/main/motorctl.cpp
@@ -1,8 +1,11 @@
 #include "motorctl.hpp"
+#include "esp_log.h"
+#include "types.hpp"
 
 //tag for logging
 static const char * TAG = "motor-control";
 
+#define TIMEOUT_IDLE_WHEN_NO_COMMAND 8000
 
 //=============================
 //======== constructor ========
@@ -77,9 +80,11 @@ void controlledMotor::handle(){
     //--- receive commands from queue ---
     if( xQueueReceive( commandQueue, &commandReceive, ( TickType_t ) 0 ) )
     {
-        ESP_LOGD(TAG, "Read command from queue: state=%s, duty=%.2f", motorstateStr[(int)commandReceive.state], commandReceive.duty);
+        ESP_LOGI(TAG, "Read command from queue: state=%s, duty=%.2f", motorstateStr[(int)commandReceive.state], commandReceive.duty);
         state = commandReceive.state;
         dutyTarget = commandReceive.duty;
+		receiveTimeout = false;
+		timestamp_commandReceived = esp_log_timestamp();
 
         //--- convert duty ---
         //define target duty (-100 to 100) from provided duty and motorstate
@@ -88,7 +93,8 @@ void controlledMotor::handle(){
             case motorstate_t::BRAKE:
                 //update state
                 state = motorstate_t::BRAKE;
-                dutyTarget = 0;
+                //dutyTarget = 0;
+                dutyTarget = fabs(commandReceive.duty);
                 break;
             case motorstate_t::IDLE:
                 dutyTarget = 0;
@@ -102,6 +108,15 @@ void controlledMotor::handle(){
         }
     }
 
+	//--- timeout, no data ---
+	//turn motors off if no data received for long time (e.g. no uart data / control offline)
+	//TODO no timeout when braking?
+	if ((esp_log_timestamp() - timestamp_commandReceived) > TIMEOUT_IDLE_WHEN_NO_COMMAND && !receiveTimeout){
+		receiveTimeout = true;
+		state = motorstate_t::IDLE;
+		dutyTarget = 0;
+		ESP_LOGE(TAG, "TIMEOUT, no target data received for more than %ds -> switch to IDLE", TIMEOUT_IDLE_WHEN_NO_COMMAND/1000);
+	}
 
     //--- calculate increment ---
     //calculate increment for fading UP with passed time since last run and configured fade time
@@ -119,14 +134,15 @@ void controlledMotor::handle(){
         dutyIncrementDecel = 100;
     }
 
-    
-    //--- BRAKE ---
-    //brake immediately, update state, duty and exit this cycle of handle function
-    if (state == motorstate_t::BRAKE){
-                motor.set(motorstate_t::BRAKE, 0);
-                dutyNow = 0;
-                return; //no need to run the fade algorithm
-    }
+
+	//--- BRAKE ---
+	//brake immediately, update state, duty and exit this cycle of handle function
+	if (state == motorstate_t::BRAKE){
+		ESP_LOGD(TAG, "braking - skip fading");
+		motor.set(motorstate_t::BRAKE, dutyTarget);
+		//dutyNow = 0;
+		return; //no need to run the fade algorithm
+	}
 
 
     //--- calculate difference ---
diff --git a/main/motorctl.hpp b/board_motorctl/main/motorctl.hpp
similarity index 73%
rename from main/motorctl.hpp
rename to board_motorctl/main/motorctl.hpp
index c4bc19e..32018be 100644
--- a/main/motorctl.hpp
+++ b/board_motorctl/main/motorctl.hpp
@@ -16,33 +16,9 @@ extern "C"
 //=======================================
 //====== struct/type  declarations ======
 //=======================================
+//outsourced to common/types.hpp
+#include "types.hpp"
 
-//struct for sending command for one motor in the queue
-struct motorCommand_t {
-    motorstate_t state;
-    float duty;
-};
-
-//struct containing commands for two motors
-typedef struct motorCommands_t {
-    motorCommand_t left;
-    motorCommand_t right;
-} motorCommands_t;
-
-//struct with all config parameters for a motor regarding ramp and current limit
-typedef struct motorctl_config_t {
-    uint32_t msFadeAccel; //acceleration of the motor (ms it takes from 0% to 100%)
-    uint32_t msFadeDecel; //deceleration of the motor (ms it takes from 100% to 0%)
-	bool currentLimitEnabled;
-	adc1_channel_t currentSensor_adc;
-	float currentSensor_ratedCurrent;
-    float currentMax;
-	uint32_t deadTimeMs; //time motor stays in IDLE before direction change
-} motorctl_config_t;
-
-//enum fade type (acceleration, deceleration)
-//e.g. used for specifying which fading should be modified with setFade, togleFade functions
-enum class fadeType_t {ACCEL, DECEL};
 
 
 
@@ -101,4 +77,7 @@ class controlledMotor {
 
         struct motorCommand_t commandReceive = {};
         struct motorCommand_t commandSend = {};
+
+		uint32_t timestamp_commandReceived = 0;
+		bool receiveTimeout = false;
 };
diff --git a/main/motordrivers.cpp b/board_motorctl/main/motordrivers.cpp
similarity index 67%
rename from main/motordrivers.cpp
rename to board_motorctl/main/motordrivers.cpp
index e15b4e6..580db57 100644
--- a/main/motordrivers.cpp
+++ b/board_motorctl/main/motordrivers.cpp
@@ -1,4 +1,6 @@
 #include "motordrivers.hpp"
+#include "esp_log.h"
+#include "types.hpp"
 
 //TODO: move from ledc to mcpwm?
 //https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32/api-reference/peripherals/mcpwm.html#
@@ -7,12 +9,11 @@
 //Note fade functionality provided by LEDC would be very useful but unfortunately is not usable here because:
 //"Due to hardware limitations, there is no way to stop a fade before it reaches its target duty."
 
-//definition of string array to be able to convert state enum to readable string
-const char* motorstateStr[4] = {"IDLE", "FWD", "REV", "BRAKE"};
-
 //tag for logging
 static const char * TAG = "motordriver";
 
+//ms to wait in IDLE before BRAKE until relay actually switched
+#define BRAKE_RELAY_DELAY_MS 300
 
 
 //====================================
@@ -64,11 +65,13 @@ void single100a::init(){
     gpio_set_direction(config.gpio_a, GPIO_MODE_OUTPUT);
     gpio_pad_select_gpio(config.gpio_b);
     gpio_set_direction(config.gpio_b, GPIO_MODE_OUTPUT);
+    gpio_pad_select_gpio(config.gpio_brakeRelay);
+    gpio_set_direction(config.gpio_brakeRelay, GPIO_MODE_OUTPUT);
 
     //--- calculate max duty according to selected resolution ---
     dutyMax = pow(2, ledc_timer.duty_resolution) -1;
-    ESP_LOGI(TAG, "initialized single100a driver");
-    ESP_LOGI(TAG, "resolution=%dbit, dutyMax value=%d, resolution=%.4f %%", ledc_timer.duty_resolution, dutyMax, 100/(float)dutyMax);
+    ESP_LOGW(TAG, "initialized single100a driver");
+    ESP_LOGW(TAG, "resolution=%dbit, dutyMax value=%d, resolution=%.4f %%", ledc_timer.duty_resolution, dutyMax, 100/(float)dutyMax);
 }
 
 
@@ -83,7 +86,7 @@ void single100a::set(motorstate_t state_f, float duty_f){
     uint32_t dutyScaled;
     if (duty_f > 100) { //target duty above 100%
         dutyScaled = dutyMax;
-    } else if (duty_f <= 0) { //target at or below 0%
+    } else if (duty_f < 0) { //target at or below 0%
 		state_f = motorstate_t::IDLE;
         dutyScaled = 0;
     } else { //target duty 0-100%
@@ -91,7 +94,18 @@ void single100a::set(motorstate_t state_f, float duty_f){
         dutyScaled = duty_f / 100 * dutyMax;
     }
 
+    ESP_LOGV(TAG, "target-state=%s, duty=%d/%d, duty_input=%.3f%%", motorstateStr[(int)state_f], dutyScaled, dutyMax, duty_f);
+
+	//TODO: only when previous mode was BRAKE?
+	if (state_f != motorstate_t::BRAKE){
+		//reset brake wait state
+		brakeWaitingForRelay = false;
+		//turn of brake relay
+		gpio_set_level(config.gpio_brakeRelay, 0);
+	}
+
     //put the single100a h-bridge module in the desired state update duty-cycle
+	//TODO maybe outsource mode code from once switch case? e.g. idle() brake()...
     switch (state_f){
         case motorstate_t::IDLE:
             ledc_set_duty(LEDC_HIGH_SPEED_MODE, config.ledc_channel, dutyScaled); 
@@ -103,13 +117,37 @@ void single100a::set(motorstate_t state_f, float duty_f){
             gpio_set_level(config.gpio_a, config.aEnabledPinState);
             gpio_set_level(config.gpio_b, config.bEnabledPinState);
             break;
-        case motorstate_t::BRAKE:
-            ledc_set_duty(LEDC_HIGH_SPEED_MODE, config.ledc_channel, 0);
-            ledc_update_duty(LEDC_HIGH_SPEED_MODE, config.ledc_channel);
-            //brake:
-            gpio_set_level(config.gpio_a, !config.aEnabledPinState);
-            gpio_set_level(config.gpio_b, !config.bEnabledPinState);
-            break;
+
+		case motorstate_t::BRAKE:
+			//prevent full short (no brake resistors) due to slow relay, also reduces switching load
+			if (!brakeWaitingForRelay){
+				ESP_LOGW(TAG, "BRAKE: turned on relay, waiting in IDLE for %d ms, then apply brake", BRAKE_RELAY_DELAY_MS);
+				//switch driver to IDLE for now
+				gpio_set_level(config.gpio_a, config.aEnabledPinState);
+				gpio_set_level(config.gpio_b, config.bEnabledPinState);
+				//start brake relay
+				gpio_set_level(config.gpio_brakeRelay, 1);
+				timestamp_brakeRelayPowered = esp_log_timestamp();
+				brakeWaitingForRelay = true;
+			}
+			//check if delay for relay to switch has passed
+			else if ((esp_log_timestamp() - timestamp_brakeRelayPowered) > BRAKE_RELAY_DELAY_MS) { 
+				ESP_LOGD(TAG, "applying brake with brake-resistors at duty=%.2f%%", duty_f);
+				//switch driver to BRAKE
+				gpio_set_level(config.gpio_a, !config.aEnabledPinState);
+				gpio_set_level(config.gpio_b, !config.bEnabledPinState);
+				//apply duty
+				//FIXME switch between BREAK and IDLE with PWM and ignore pwm-pin? (needs test)
+				ledc_set_duty(LEDC_HIGH_SPEED_MODE, config.ledc_channel, dutyScaled);
+				ledc_update_duty(LEDC_HIGH_SPEED_MODE, config.ledc_channel);
+			} else {
+				//waiting... stay in IDLE
+				ESP_LOGD(TAG, "waiting for brake relay to close (IDLE)...");
+				gpio_set_level(config.gpio_a, config.aEnabledPinState);
+				gpio_set_level(config.gpio_b, config.bEnabledPinState);
+			}
+			break;
+
         case motorstate_t::FWD:
             ledc_set_duty(LEDC_HIGH_SPEED_MODE, config.ledc_channel, dutyScaled);
             ledc_update_duty(LEDC_HIGH_SPEED_MODE, config.ledc_channel);
@@ -117,6 +155,7 @@ void single100a::set(motorstate_t state_f, float duty_f){
             gpio_set_level(config.gpio_a, config.aEnabledPinState);
             gpio_set_level(config.gpio_b, !config.bEnabledPinState);
             break;
+
         case motorstate_t::REV:
             ledc_set_duty(LEDC_HIGH_SPEED_MODE, config.ledc_channel, dutyScaled);
             ledc_update_duty(LEDC_HIGH_SPEED_MODE, config.ledc_channel);
@@ -125,5 +164,4 @@ void single100a::set(motorstate_t state_f, float duty_f){
             gpio_set_level(config.gpio_b, config.bEnabledPinState);
             break;
     }
-    ESP_LOGD(TAG, "set module to state=%s, duty=%d/%d, duty_input=%.3f%%", motorstateStr[(int)state_f], dutyScaled, dutyMax, duty_f);
 }
diff --git a/main/motordrivers.hpp b/board_motorctl/main/motordrivers.hpp
similarity index 85%
rename from main/motordrivers.hpp
rename to board_motorctl/main/motordrivers.hpp
index 2cc3c75..745cbf3 100644
--- a/main/motordrivers.hpp
+++ b/board_motorctl/main/motordrivers.hpp
@@ -21,17 +21,15 @@ extern "C"
 //--------------------------------------------
 //---- struct, enum, variable declarations ---
 //--------------------------------------------
-
-//class which controls a motor using a 'single100a' h-bridge module
-enum class motorstate_t {IDLE, FWD, REV, BRAKE};
-//definition of string array to be able to convert state enum to readable string (defined in motordrivers.cpp)
-extern const char* motorstateStr[4];
+//motorstate_t, motorstateStr outsourced to common/types.hpp
+#include "types.hpp"
 
 //struct with all config parameters for single100a motor driver
 typedef struct single100a_config_t {
     gpio_num_t gpio_pwm;
     gpio_num_t gpio_a;
     gpio_num_t gpio_b;
+	gpio_num_t gpio_brakeRelay;
     ledc_timer_t ledc_timer;
     ledc_channel_t ledc_channel;
 	bool aEnabledPinState;
@@ -62,4 +60,6 @@ class single100a {
         single100a_config_t config;
         uint32_t dutyMax;
         motorstate_t state = motorstate_t::IDLE;
+		bool brakeWaitingForRelay = false;
+		uint32_t timestamp_brakeRelayPowered;
 };
diff --git a/board_motorctl/main/uart.cpp b/board_motorctl/main/uart.cpp
new file mode 100644
index 0000000..3bdc283
--- /dev/null
+++ b/board_motorctl/main/uart.cpp
@@ -0,0 +1,71 @@
+#include "uart.hpp"
+#include "config.hpp"
+#include "types.hpp"
+#include "uart_common.hpp"
+//===== uart board MOTORCTL =====
+
+static const char * TAG = "uart";
+
+
+
+//handle received payload from uart
+void handleMessage(uint8_t *receivedData, int len) {
+	ESP_LOGI(TAG, "complete message received len=%d", len);
+	//local variables
+	uartData_test_t dataTest;
+	motorCommands_t dataMotorCommands;
+	//assign data to struct
+	switch (len){
+		case sizeof(uartData_test_t):
+			dataTest = serialData2Struct<uartData_test_t>(receivedData);
+			ESP_LOGW(TAG, "received uartDataStruct len=%d DATA: timestamp=%d, id=%d, value=%.1f", len, dataTest.timestamp, dataTest.id, dataTest.value);
+			break;
+
+		case sizeof(motorCommands_t):
+			dataMotorCommands = serialData2Struct<motorCommands_t>(receivedData);
+			ESP_LOGI(TAG, "received motorCommands struct len=%d left=%.2f%% right=%.2f%%, update target...", len, dataMotorCommands.left.duty, dataMotorCommands.right.duty);
+			//update target motor state and duty
+			motorLeft.setTarget(dataMotorCommands.left.state, 
+					dataMotorCommands.left.duty);
+			motorRight.setTarget(dataMotorCommands.right.state, 
+					dataMotorCommands.right.duty);
+			break;
+
+			//TODO add other received structs here
+		default:
+			ESP_LOGE(TAG, "received data len=%d cant be associated with configures struct", len);
+			break;
+	}
+}
+
+
+
+//==============================
+//====== task_uartReceive ======
+//==============================
+//TODO duplicate code, same task in both boards, only handleMessage function has to be passed -> move to uart_common
+void task_uartReceive(void *arg){
+	ESP_LOGW(TAG, "receive task started");
+	while (1) {
+		uint8_t byte;
+		//read 1 byte TODO: use uart queue here? data might get lost when below function takes longer than data arrives
+		int len = uart_read_bytes(UART_NUM_1, &byte, 1, portMAX_DELAY);
+		if (len > 0) {
+			//process received byte
+			uart_processReceivedByte(byte, handleMessage);
+		}
+	}
+}
+
+
+
+//=============================
+//======= task_uartSend =======
+//=============================
+//TODO copy send task from board_control/uart.cpp
+void task_uartSend(void *arg){
+	ESP_LOGW(TAG, "send task started");
+	while (1) {
+		vTaskDelay(500 / portTICK_PERIOD_MS);    
+	}
+}
diff --git a/board_motorctl/main/uart.hpp b/board_motorctl/main/uart.hpp
new file mode 100644
index 0000000..b94c767
--- /dev/null
+++ b/board_motorctl/main/uart.hpp
@@ -0,0 +1,8 @@
+#pragma once
+#include "uart_common.hpp"
+
+//===== uart board MOTORCTL =====
+
+void task_uartReceive(void *arg);
+void task_uartSend(void *arg);
+
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
new file mode 100644
index 0000000..a49da26
--- /dev/null
+++ b/common/CMakeLists.txt
@@ -0,0 +1,11 @@
+idf_component_register(
+    SRCS 
+        "wifi.c"
+		"buzzer.cpp"
+		"uart_common.cpp"
+		"types.cpp"
+    INCLUDE_DIRS 
+        "."
+		PRIV_REQUIRES nvs_flash
+    )
+
diff --git a/main/buzzer.cpp b/common/buzzer.cpp
similarity index 99%
rename from main/buzzer.cpp
rename to common/buzzer.cpp
index 9046cd1..0850116 100644
--- a/main/buzzer.cpp
+++ b/common/buzzer.cpp
@@ -1,5 +1,4 @@
 #include "buzzer.hpp"
-#include "config.hpp"
 
 static const char *TAG_BUZZER = "buzzer";
 
diff --git a/main/buzzer.hpp b/common/buzzer.hpp
similarity index 100%
rename from main/buzzer.hpp
rename to common/buzzer.hpp
diff --git a/common/types.cpp b/common/types.cpp
new file mode 100644
index 0000000..6c0d3bb
--- /dev/null
+++ b/common/types.cpp
@@ -0,0 +1,4 @@
+#include "types.hpp"
+
+
+const char* motorstateStr[4] = {"IDLE", "FWD", "REV", "BRAKE"};
diff --git a/common/types.hpp b/common/types.hpp
new file mode 100644
index 0000000..6cf868e
--- /dev/null
+++ b/common/types.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+extern "C"
+{
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "esp_timer.h"
+#include <driver/adc.h>
+}
+//=======================================
+//====== struct/type  declarations ======
+//=======================================
+//global structs and types that need to be available for all boards
+
+
+//===============================
+//==== from motordrivers.hpp ====
+//===============================
+enum class motorstate_t {IDLE, FWD, REV, BRAKE};
+//definition of string array to be able to convert state enum to readable string (defined in motordrivers.cpp)
+extern const char* motorstateStr[4];
+
+
+
+//===========================
+//==== from motorctl.hpp ====
+//===========================
+//struct for sending command for one motor in the queue
+struct motorCommand_t {
+    motorstate_t state;
+    float duty;
+};
+
+//struct containing commands for two motors
+typedef struct motorCommands_t {
+    motorCommand_t left;
+    motorCommand_t right;
+} motorCommands_t;
+
+//struct with all config parameters for a motor regarding ramp and current limit
+typedef struct motorctl_config_t {
+    uint32_t msFadeAccel; //acceleration of the motor (ms it takes from 0% to 100%)
+    uint32_t msFadeDecel; //deceleration of the motor (ms it takes from 100% to 0%)
+	bool currentLimitEnabled;
+	adc1_channel_t currentSensor_adc;
+	float currentSensor_ratedCurrent;
+    float currentMax;
+	uint32_t deadTimeMs; //time motor stays in IDLE before direction change
+} motorctl_config_t;
+
+//enum fade type (acceleration, deceleration)
+//e.g. used for specifying which fading should be modified with setFade, togleFade functions
+enum class fadeType_t {ACCEL, DECEL};
+
diff --git a/common/uart_common.cpp b/common/uart_common.cpp
new file mode 100644
index 0000000..48db8d6
--- /dev/null
+++ b/common/uart_common.cpp
@@ -0,0 +1,117 @@
+#include "uart_common.hpp"
+
+static const char * TAG = "uart-common";
+SemaphoreHandle_t uart_semaphoreSend = NULL;
+bool uart_isInitialized = false;
+
+
+
+//===========================
+//======== uart_init  =======
+//===========================
+//initial struct on given pins
+//TODO add pins and baud rate to config?
+void uart_init(void){
+	ESP_LOGW(TAG, "initializing uart1...");
+	uart_semaphoreSend = xSemaphoreCreateBinary();
+	uart_config_t uart1_config = {
+		.baud_rate = 115198,
+		.data_bits = UART_DATA_8_BITS,
+		.parity    = UART_PARITY_EVEN,
+		.stop_bits = UART_STOP_BITS_1,
+		.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
+	};
+	ESP_LOGI(TAG, "configure...");
+	ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart1_config));
+	ESP_LOGI(TAG, "setpins...");
+	ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, 23, 22, 0, 0));
+	ESP_LOGI(TAG, "init...");
+	ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, 1024, 1024, 10, NULL, 0));
+	uart_isInitialized = true;
+	xSemaphoreGive(uart_semaphoreSend);
+}
+
+
+
+//===========================
+//===== uart_sendBinary  ====
+//===========================
+//encode byte array to message (start, stop, escape pattern)
+//and send it via uart
+//note: use sendStruct template in uart_common.hpp
+void uart_sendBinary(uint8_t *data, int length) {
+	const uint8_t startPattern = START_PATTERN;
+	const uint8_t endPattern = END_PATTERN;
+	const uint8_t escapeByte = ESCAPE_BYTE;
+	ESP_LOGI(TAG, "encoding and sending bytes len=%d", length);
+	//wait for last message to finish sending
+	if (xSemaphoreTake(uart_semaphoreSend, UART_WRITE_WAIT_TIMEOUT / portTICK_PERIOD_MS) == pdTRUE){
+		//send start byte
+		uart_write_bytes(UART_NUM_1, &startPattern, 1);
+
+		for (int i = 0; i < length; i++) {
+			if (data[i] == START_PATTERN || data[i] == END_PATTERN || data[i] == ESCAPE_BYTE) {
+				//add escape byte if next byte is special pattern by accident
+				uart_write_bytes(UART_NUM_1, &escapeByte, 1);
+			}
+			uart_write_bytes(UART_NUM_1, (const char *)&data[i], 1);
+		}
+		//send end byte
+		uart_write_bytes(UART_NUM_1, &endPattern, 1);
+		vTaskDelay(UART_WRITE_MIN_DELAY / portTICK_PERIOD_MS);
+		xSemaphoreGive(uart_semaphoreSend);
+	} else ESP_LOGE(TAG, "timeout waiting for uart write semaphore! dropping data");
+}
+
+
+
+
+//================================
+//=== uart_processReceivedByte ===
+//================================
+//decode received message to byte array (start, stop, escape pattern)
+//has to be run for each receibed byte
+//runs provided messageHandler function when complete message received
+uint8_t receivedData[MAX_MESSAGE_LENGTH];
+int dataIndex = 0;
+bool insideMessage = false;
+bool escaped = false;
+
+void uart_processReceivedByte(uint8_t data, messageHandleFunc_t messageHandler){
+	ESP_LOGD(TAG, "process byte %x", data);
+	if (escaped) {
+		//this byte is actual data, no end/start byte
+		escaped = false;
+		receivedData[dataIndex++] = data;
+		if (dataIndex >= MAX_MESSAGE_LENGTH) {
+			insideMessage = false;
+			dataIndex = 0;
+		}
+	} else if (data == START_PATTERN) {
+		//start of message
+		insideMessage = true;
+		dataIndex = 0;
+	} else if (insideMessage) {
+		if (data == ESCAPE_BYTE) {
+			ESP_LOGI(TAG, "escape byte received");
+			//escape next byte
+			escaped = true;
+		} else if (data == END_PATTERN) {
+			//end of message
+			insideMessage = false;
+			//call provided function that handles actual messages
+			messageHandler(receivedData, dataIndex);
+			dataIndex = 0;
+		} else if (dataIndex < MAX_MESSAGE_LENGTH - 2) {
+			//normal byte - append byte to data
+			receivedData[dataIndex++] = data;
+		} else {
+			//message too long / buffer exceeded
+			insideMessage = false;
+			dataIndex = 0;
+			ESP_LOGE(TAG, "received message too long! dropped");
+		}
+	} else ESP_LOGE(TAG, "start pattern missing! ignoreing byte");
+}
+	
+
diff --git a/common/uart_common.hpp b/common/uart_common.hpp
new file mode 100644
index 0000000..be599b7
--- /dev/null
+++ b/common/uart_common.hpp
@@ -0,0 +1,121 @@
+#pragma once
+extern "C"
+{
+#include <stdio.h>
+#include <esp_system.h>
+#include <esp_event.h>
+#include <nvs_flash.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/gpio.h"
+#include "esp_log.h"
+#include "sdkconfig.h"
+#include <string.h>
+#include "freertos/semphr.h"
+
+#include "freertos/queue.h"
+#include "driver/uart.h"
+}
+#include "types.hpp"
+
+//idea with time gap dropped, replaced with encoding
+//#define UART_RECEIVE_DURATION 10 
+//receive interval may not miss messages but also may not read multiple messages
+//has to be significantly smaller than WRITE_MNIN_DELAY but larger than longest message
+//semaphore for assuring min delay between sent data
+//extern SemaphoreHandle_t uart_semaphoreSend;
+
+//==== parameters message frame ====
+#define START_PATTERN 0xAA
+#define END_PATTERN 0xBB
+#define MAX_MESSAGE_LENGTH 1024
+#define ESCAPE_BYTE   0xCC
+//min delay after each message (no significant effect)
+#define UART_WRITE_MIN_DELAY 50
+#define UART_WRITE_WAIT_TIMEOUT 2000
+
+extern bool uart_isInitialized;
+
+//struct for testing uart
+typedef struct {
+	uint32_t timestamp;
+	int id;
+	float value;
+} uartData_test_t;
+
+
+//unnecessary, using commands struct directly
+typedef struct {
+	uint32_t timestamp;
+	motorCommands_t commands;
+} uartData_motorCommands_t;
+
+
+//function that handles receieved messages as byte array
+//-> do something with received data
+typedef void (*messageHandleFunc_t)(uint8_t *data, int length);
+
+
+
+//===== uart_init =====
+//should be run once at startup
+void uart_init(void);
+
+
+//===== uart_processReceivedByte =====
+//decode received message to byte array (start, stop, escape pattern)
+//has to be run for each receibed byte
+//runs provided messageHandler function when complete message received
+void uart_processReceivedByte(uint8_t data, messageHandleFunc_t messageHandler);
+
+
+//===== uart_sendBinary =====
+//encode byte array to message (start, stop, escape pattern)
+//and send it via uart
+void uart_sendBinary(uint8_t *data, int length);
+
+
+
+//============================
+//====== uart_sendStruct =====
+//============================
+//send and struct via uart
+//waits when another struct was sent less than UART_WRITE_MIN_DELAY ago
+template <typename T> void uart_sendStruct(T dataStruct) {
+	static const char * TAG = "uart-common";
+	//check if uart is initialized
+	if (!uart_isInitialized){
+		ESP_LOGE(TAG, "uart not initialized! droping data");
+		return;
+	}
+	uint8_t dataSerial[sizeof(T)];
+	//struct to serial bytes
+	memcpy(dataSerial, &dataStruct, sizeof(T));
+	// 	//wait for min delay after last write DROPPED
+	// 	if (xSemaphoreTake(uart_semaphoreSend, UART_WRITE_WAIT_TIMEOUT / portTICK_PERIOD_MS) == pdTRUE){
+	// 		//send bytes
+	// 		uart_write_bytes(UART_NUM_1, (const char *)dataSerial, sizeof(T));
+	// 		ESP_LOGW(TAG, "sent data struct with len %d", sizeof(T));
+	// 	} else ESP_LOGE(TAG, "timeout waiting for uart write semaphore! dropping data");
+	// 	//wait min delay before next write is allowed
+	// 	vTaskDelay(UART_WRITE_MIN_DELAY / portTICK_PERIOD_MS);
+	// 	xSemaphoreGive(uart_semaphoreSend);
+
+	uart_sendBinary(dataSerial, sizeof(T));
+}
+
+
+
+//==============================
+//====== serialData2Struct =====
+//==============================
+//convert serial data (byte array) to given struct and return it
+//note check whether serial data length actually matches size of struct is necessary before
+template <typename T> T serialData2Struct(uint8_t *dataSerial){
+	static const char * TAG = "uart-common";
+	T dataStruct;
+	memcpy(&dataStruct, dataSerial, sizeof(T));
+	ESP_LOGI(TAG, "converted serial data len=%d to struct", sizeof(T));
+	return dataStruct;
+}
+
diff --git a/main/wifi.c b/common/wifi.c
similarity index 100%
rename from main/wifi.c
rename to common/wifi.c
diff --git a/main/wifi.h b/common/wifi.h
similarity index 100%
rename from main/wifi.h
rename to common/wifi.h
diff --git a/connection-plan.drawio.pdf b/connection-plan.drawio.pdf
index 299be63..3fa53fc 100644
Binary files a/connection-plan.drawio.pdf and b/connection-plan.drawio.pdf differ
diff --git a/function-diagram.drawio.pdf b/function-diagram.drawio.pdf
index a2ef20c..38f8bf3 100644
Binary files a/function-diagram.drawio.pdf and b/function-diagram.drawio.pdf differ
diff --git a/main/auto.cpp b/main/auto.cpp
deleted file mode 100644
index 4cf4a71..0000000
--- a/main/auto.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "auto.hpp"
-#include "config.hpp"
-
-//tag for logging
-static const char * TAG = "automatedArmchair";
-
-
-//=============================
-//======== constructor ========
-//=============================
-automatedArmchair::automatedArmchair(void) {
-    //create command queue
-    commandQueue = xQueueCreate( 32, sizeof( commandSimple_t ) ); //TODO add max size to config?
-}
-
-
-
-//==============================
-//====== generateCommands ======
-//==============================
-motorCommands_t automatedArmchair::generateCommands(auto_instruction_t * instruction) {
-    //reset instruction
-    *instruction = auto_instruction_t::NONE;
-    //check if previous command is finished
-    if ( esp_log_timestamp() > timestampCmdFinished ) {
-        //get next command from queue
-        if( xQueueReceive( commandQueue, &cmdCurrent, pdMS_TO_TICKS(500) ) ) {
-            ESP_LOGI(TAG, "running next command from queue...");
-            //copy instruction to be provided to control task
-            *instruction = cmdCurrent.instruction;
-            //set acceleration / fading parameters according to command
-            motorLeft.setFade(fadeType_t::DECEL, cmdCurrent.fadeDecel);
-            motorRight.setFade(fadeType_t::DECEL, cmdCurrent.fadeDecel);
-            motorLeft.setFade(fadeType_t::ACCEL, cmdCurrent.fadeAccel);
-            motorRight.setFade(fadeType_t::ACCEL, cmdCurrent.fadeAccel);
-            //calculate timestamp the command is finished
-            timestampCmdFinished = esp_log_timestamp() + cmdCurrent.msDuration;
-            //copy the new commands
-            motorCommands = cmdCurrent.motorCmds;
-        } else { //queue empty
-            ESP_LOGD(TAG, "no new command in queue -> set motors to IDLE");
-            motorCommands = motorCmds_bothMotorsIdle;
-        }
-    } else { //previous command still running
-        ESP_LOGD(TAG, "command still running -> no change");
-    }
-
-    //TODO also return instructions via call by reference
-    return motorCommands;
-}
-
-
-
-//============================
-//======== addCommand ========
-//============================
-//function that adds a basic command to the queue
-void automatedArmchair::addCommand(commandSimple_t command) {
-    //add command to queue
-     if ( xQueueSend( commandQueue, ( void * )&command, ( TickType_t ) 0 ) ){
-         ESP_LOGI(TAG, "Successfully inserted command to queue");
-     } else {
-         ESP_LOGE(TAG, "Failed to insert new command to queue");
-     }
-}
-
-void automatedArmchair::addCommands(commandSimple_t commands[], size_t count) {
-    for (int i = 0; i < count; i++) {
-         ESP_LOGI(TAG, "Reading command no. %d from provided array", i);
-        addCommand(commands[i]);
-    }
-}
-
-
-//===============================
-//======== clearCommands ========
-//===============================
-//function that deletes all pending/queued commands
-//e.g. when switching modes
-motorCommands_t automatedArmchair::clearCommands() {
-    //clear command queue
-    xQueueReset( commandQueue );
-    ESP_LOGW(TAG, "command queue was successfully emptied");
-    //return commands for idling both motors
-    motorCommands = motorCmds_bothMotorsIdle;
-    return motorCmds_bothMotorsIdle;
-}
-
diff --git a/main/button.cpp b/main/button.cpp
deleted file mode 100644
index 1762e6e..0000000
--- a/main/button.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-extern "C"
-{
-#include <stdio.h>
-#include <esp_system.h>
-#include <esp_event.h>
-#include "freertos/FreeRTOS.h"
-#include "esp_log.h"
-}
-
-#include "button.hpp"
-
-
-
-//tag for logging
-static const char * TAG = "button";
-
-
-
-//-----------------------------
-//-------- constructor --------
-//-----------------------------
-buttonCommands::buttonCommands(gpio_evaluatedSwitch * button_f, evaluatedJoystick * joystick_f, controlledArmchair * control_f, buzzer_t * buzzer_f, controlledMotor * motorLeft_f, controlledMotor * motorRight_f){
-    //copy object pointers
-    button = button_f;
-    joystick = joystick_f;
-    control = control_f;
-    buzzer = buzzer_f;
-    motorLeft = motorLeft_f;
-    motorRight = motorRight_f;
-    //TODO declare / configure evaluatedSwitch here instead of config (unnecessary that button object is globally available - only used here)?
-}
-
-
-
-//----------------------------
-//--------- action -----------
-//----------------------------
-//function that runs commands depending on a count value
-void buttonCommands::action (uint8_t count, bool lastPressLong){
-    //--- variable declarations ---
-    bool decelEnabled; //for different beeping when toggling
-    commandSimple_t cmds[8]; //array for commands for automatedArmchair
-
-    //--- get joystick position ---
-    //joystickData_t stickData = joystick->getData();
-
-    //--- actions based on count ---
-    switch (count){
-        //no such command
-        default:
-            ESP_LOGE(TAG, "no command for count=%d defined", count);
-            buzzer->beep(3, 400, 100);
-            break;
-
-        case 1:
-            //restart contoller when 1x long pressed
-            if (lastPressLong){
-                ESP_LOGW(TAG, "RESTART");
-                buzzer->beep(1,1000,1);
-                vTaskDelay(1000 / portTICK_PERIOD_MS);
-                esp_restart();
-                return;
-            } 
-
-            ESP_LOGW(TAG, "cmd %d: sending button event to control task", count);
-            //-> define joystick center or toggle freeze input (executed in control task)
-            control->sendButtonEvent(count); //TODO: always send button event to control task (not just at count=1) -> control.cpp has to be changed
-            break;
-        case 2:
-            //run automatic commands to lift leg support when pressed 1x short 1x long
-            if (lastPressLong){
-                //define commands
-                cmds[0] =
-                {
-                    .motorCmds = {
-                        .left = {motorstate_t::REV, 90},
-                        .right = {motorstate_t::REV, 90}
-                    },
-                    .msDuration = 1200,
-                    .fadeDecel = 800,
-                    .fadeAccel = 1300,
-                    .instruction = auto_instruction_t::NONE
-                };
-                cmds[1] =
-                {
-                    .motorCmds = {
-                        .left = {motorstate_t::FWD, 70},
-                        .right = {motorstate_t::FWD, 70}
-                    },
-                    .msDuration = 70,
-                    .fadeDecel = 0,
-                    .fadeAccel = 300,
-                    .instruction = auto_instruction_t::NONE
-                };
-                cmds[2] =
-                {
-                    .motorCmds = {
-                        .left = {motorstate_t::IDLE, 0},
-                        .right = {motorstate_t::IDLE, 0}
-                    },
-                    .msDuration = 10,
-                    .fadeDecel = 800,
-                    .fadeAccel = 1300,
-                    .instruction = auto_instruction_t::SWITCH_JOYSTICK_MODE
-                };
-
-                //send commands to automatedArmchair command queue
-                armchair.addCommands(cmds, 3);
-
-                //change mode to AUTO
-                control->changeMode(controlMode_t::AUTO);
-                return;
-            }
-
-            //toggle idle when 2x pressed
-            ESP_LOGW(TAG, "cmd %d: toggle IDLE", count);
-            control->toggleIdle(); //toggle between idle and previous/default mode
-            break;
-
-
-        case 3:
-            ESP_LOGW(TAG, "cmd %d: switch to JOYSTICK", count);
-            control->changeMode(controlMode_t::JOYSTICK); //switch to JOYSTICK mode
-            break;
-
-        case 4:
-            ESP_LOGW(TAG, "cmd %d: toggle between HTTP and JOYSTICK", count);
-            control->toggleModes(controlMode_t::HTTP, controlMode_t::JOYSTICK); //toggle between HTTP and JOYSTICK mode
-            break;
-
-        case 6:
-            ESP_LOGW(TAG, "cmd %d: toggle between MASSAGE and JOYSTICK", count);
-            control->toggleModes(controlMode_t::MASSAGE, controlMode_t::JOYSTICK); //toggle between MASSAGE and JOYSTICK mode
-            break;
-
-        case 8:
-            //toggle deceleration fading between on and off
-            decelEnabled = motorLeft->toggleFade(fadeType_t::DECEL);
-            motorRight->toggleFade(fadeType_t::DECEL);
-            ESP_LOGW(TAG, "cmd %d: toggle deceleration fading to: %d", count, (int)decelEnabled);
-            if (decelEnabled){
-                buzzer->beep(3, 60, 50);
-            } else {
-                buzzer->beep(1, 1000, 1);
-            }
-            break;
-
-        case 12:
-            ESP_LOGW(TAG, "cmd %d: sending button event to control task", count);
-            //-> toggle altStickMapping (executed in control task)
-            control->sendButtonEvent(count); //TODO: always send button event to control task (not just at count=1)?
-            break;
-
-    }
-}
-
-
-
-
-//-----------------------------
-//------ startHandleLoop ------
-//-----------------------------
-//this function has to be started once in a separate task
-//repeatedly evaluates and processes button events then takes the corresponding action
-void buttonCommands::startHandleLoop() {
-
-    while(1) {
-        vTaskDelay(20 / portTICK_PERIOD_MS);
-        //run handle function of evaluatedSwitch object
-        button->handle();
-
-        //--- count button presses and run action ---
-        switch(state) {
-            case inputState_t::IDLE: //wait for initial button press
-                if (button->risingEdge) {
-                    count = 1;
-                    buzzer->beep(1, 65, 0);
-                    timestamp_lastAction = esp_log_timestamp();
-                    state = inputState_t::WAIT_FOR_INPUT;
-                    ESP_LOGI(TAG, "first button press detected -> waiting for further events");
-                }
-                break;
-
-            case inputState_t::WAIT_FOR_INPUT: //wait for further presses
-                //button pressed again
-                if (button->risingEdge){
-                    count++;
-                    buzzer->beep(1, 65, 0);
-                    timestamp_lastAction = esp_log_timestamp();
-                    ESP_LOGI(TAG, "another press detected -> count=%d -> waiting for further events", count);
-                }
-                //timeout
-                else if (esp_log_timestamp() - timestamp_lastAction > 1000) {
-                    state = inputState_t::IDLE;
-                    buzzer->beep(count, 50, 50);
-                    //TODO: add optional "bool wait" parameter to beep function to delay until finished beeping
-                    ESP_LOGI(TAG, "timeout - running action function for count=%d", count);
-                    //--- run action function ---
-                    //check if still pressed
-                    bool lastPressLong = false;
-                    if (button->state == true){
-                        //run special case when last press was longer than timeout
-                        lastPressLong = true;
-                    }
-                        //run action function with current count of button presses
-                        action(count, lastPressLong);
-                    }
-                break;
-        }
-    }
-}
-
-
-
-
diff --git a/main/button.hpp b/main/button.hpp
deleted file mode 100644
index 09de729..0000000
--- a/main/button.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include "gpio_evaluateSwitch.hpp"
-#include "buzzer.hpp"
-#include "control.hpp"
-#include "motorctl.hpp"
-#include "auto.hpp"
-#include "config.hpp"
-#include "joystick.hpp"
-
-
-
-//===================================
-//====== buttonCommands class =======
-//===================================
-//class which runs commands depending on the count a button was pressed
-class buttonCommands {
-    public:
-        //--- constructor ---
-        buttonCommands (
-                gpio_evaluatedSwitch * button_f,
-                evaluatedJoystick * joystick_f,
-                controlledArmchair * control_f,
-                buzzer_t * buzzer_f,
-                controlledMotor * motorLeft_f, 
-                controlledMotor * motorRight_f
-                ); 
-
-        //--- functions ---
-        //the following function has to be started once in a separate task. 
-        //repeatedly evaluates and processes button events then takes the corresponding action
-        void startHandleLoop(); 
-
-    private:
-        //--- functions ---
-        void action(uint8_t count, bool lastPressLong);
-
-        //--- objects ---
-        gpio_evaluatedSwitch* button;
-        evaluatedJoystick* joystick;
-        controlledArmchair * control;
-        buzzer_t* buzzer;
-        controlledMotor * motorLeft;
-        controlledMotor * motorRight;
-
-        //--- variables ---
-        uint8_t count = 0;
-        uint32_t timestamp_lastAction = 0;
-        enum class inputState_t {IDLE, WAIT_FOR_INPUT};
-        inputState_t state = inputState_t::IDLE;
-
-};
-
diff --git a/main/control.cpp b/main/control.cpp
deleted file mode 100644
index fc9e4e3..0000000
--- a/main/control.cpp
+++ /dev/null
@@ -1,479 +0,0 @@
-extern "C"
-{
-#include <stdio.h>
-#include "freertos/FreeRTOS.h"
-#include "esp_log.h"
-#include "freertos/queue.h"
-
-//custom C libraries
-#include "wifi.h"
-}
-
-#include "config.hpp"
-#include "control.hpp"
-
-
-//used definitions moved from config.hpp:
-//#define JOYSTICK_TEST
-
-
-//tag for logging
-static const char * TAG = "control";
-const char* controlModeStr[7] = {"IDLE", "JOYSTICK", "MASSAGE", "HTTP", "MQTT", "BLUETOOTH", "AUTO"};
-
-
-//-----------------------------
-//-------- constructor --------
-//-----------------------------
-controlledArmchair::controlledArmchair (
-        control_config_t config_f,
-        buzzer_t * buzzer_f,
-        controlledMotor* motorLeft_f,
-        controlledMotor* motorRight_f,
-        evaluatedJoystick* joystick_f,
-        httpJoystick* httpJoystick_f
-        ){
-
-    //copy configuration
-    config = config_f;
-    //copy object pointers
-    buzzer = buzzer_f;
-    motorLeft = motorLeft_f;
-    motorRight = motorRight_f;
-    joystick_l = joystick_f,
-    httpJoystickMain_l = httpJoystick_f;
-    //set default mode from config
-    modePrevious = config.defaultMode;
-    
-    //TODO declare / configure controlled motors here instead of config (unnecessary that button object is globally available - only used here)?
-}
-
-
-
-//----------------------------------
-//---------- Handle loop -----------
-//----------------------------------
-//function that repeatedly generates motor commands depending on the current mode
-//also handles fading and current-limit
-void controlledArmchair::startHandleLoop() {
-    while (1){
-        ESP_LOGV(TAG, "control task executing... mode=%s", controlModeStr[(int)mode]);
-
-        switch(mode) {
-            default:
-                mode = controlMode_t::IDLE;
-                break;
-
-            case controlMode_t::IDLE:
-                //copy preset commands for idling both motors
-                commands = cmds_bothMotorsIdle;
-                motorRight->setTarget(commands.right.state, commands.right.duty); 
-                motorLeft->setTarget(commands.left.state, commands.left.duty); 
-                vTaskDelay(200 / portTICK_PERIOD_MS);
-#ifdef JOYSTICK_LOG_IN_IDLE
-				//get joystick data here (without using it)
-				//since loglevel is DEBUG, calculateion details is output
-                joystick_l->getData(); //get joystick data here
-#endif
-                break;
-
-
-            case controlMode_t::JOYSTICK:
-                vTaskDelay(20 / portTICK_PERIOD_MS);
-                //get current joystick data with getData method of evaluatedJoystick
-                stickData = joystick_l->getData();
-                //additionaly scale coordinates (more detail in slower area)
-                joystick_scaleCoordinatesLinear(&stickData, 0.6, 0.35); //TODO: add scaling parameters to config
-                //generate motor commands
-                commands = joystick_generateCommandsDriving(stickData, altStickMapping);
-                //apply motor commands
-                motorRight->setTarget(commands.right.state, commands.right.duty); 
-                motorLeft->setTarget(commands.left.state, commands.left.duty); 
-                //TODO make motorctl.setTarget also accept motorcommand struct directly
-                break;
-
-
-            case controlMode_t::MASSAGE:
-                vTaskDelay(10 / portTICK_PERIOD_MS);
-                //--- read joystick ---
-                //only update joystick data when input not frozen
-                if (!freezeInput){
-                    stickData = joystick_l->getData();
-                }
-                //--- generate motor commands ---
-                //pass joystick data from getData method of evaluatedJoystick to generateCommandsShaking function
-                commands = joystick_generateCommandsShaking(stickData);
-                //apply motor commands
-                motorRight->setTarget(commands.right.state, commands.right.duty); 
-                motorLeft->setTarget(commands.left.state, commands.left.duty); 
-                break;
-
-
-            case controlMode_t::HTTP:
-                //--- get joystick data from queue ---
-                //Note this function waits several seconds (httpconfig.timeoutMs) for data to arrive, otherwise Center data or NULL is returned
-                //TODO: as described above, when changing modes it might delay a few seconds for the change to apply
-                stickData = httpJoystickMain_l->getData();
-                //scale coordinates additionally (more detail in slower area)
-                joystick_scaleCoordinatesLinear(&stickData, 0.6, 0.4); //TODO: add scaling parameters to config
-                ESP_LOGD(TAG, "generating commands from x=%.3f  y=%.3f  radius=%.3f  angle=%.3f", stickData.x, stickData.y, stickData.radius, stickData.angle);
-                //--- generate motor commands ---
-                //Note: timeout (no data received) is handled in getData method
-                commands = joystick_generateCommandsDriving(stickData, altStickMapping);
-
-                //--- apply commands to motors ---
-                //TODO make motorctl.setTarget also accept motorcommand struct directly
-                motorRight->setTarget(commands.right.state, commands.right.duty); 
-                motorLeft->setTarget(commands.left.state, commands.left.duty); 
-               break;
-
-
-            case controlMode_t::AUTO:
-                vTaskDelay(20 / portTICK_PERIOD_MS);
-               //generate commands
-               commands = armchair.generateCommands(&instruction);
-                //--- apply commands to motors ---
-                //TODO make motorctl.setTarget also accept motorcommand struct directly
-               motorRight->setTarget(commands.right.state, commands.right.duty); 
-               motorLeft->setTarget(commands.left.state, commands.left.duty); 
-
-               //process received instruction
-               switch (instruction) {
-                   case auto_instruction_t::NONE:
-                       break;
-                   case auto_instruction_t::SWITCH_PREV_MODE:
-                       toggleMode(controlMode_t::AUTO);
-                       break;
-                   case auto_instruction_t::SWITCH_JOYSTICK_MODE:
-                       changeMode(controlMode_t::JOYSTICK);
-                       break;
-                   case auto_instruction_t::RESET_ACCEL_DECEL:
-                       //enable downfading (set to default value)
-                       motorLeft->setFade(fadeType_t::DECEL, true);
-                       motorRight->setFade(fadeType_t::DECEL, true);
-                       //set upfading to default value
-                       motorLeft->setFade(fadeType_t::ACCEL, true);
-                       motorRight->setFade(fadeType_t::ACCEL, true);
-                       break;
-                   case auto_instruction_t::RESET_ACCEL:
-                       //set upfading to default value
-                       motorLeft->setFade(fadeType_t::ACCEL, true);
-                       motorRight->setFade(fadeType_t::ACCEL, true);
-                       break;
-                   case auto_instruction_t::RESET_DECEL:
-                       //enable downfading (set to default value)
-                       motorLeft->setFade(fadeType_t::DECEL, true);
-                       motorRight->setFade(fadeType_t::DECEL, true);
-                       break;
-               }
-               break;
-
-
-              //TODO: add other modes here
-        }
-
-
-        //--- run actions based on received button button event ---
-		//note: buttonCount received by sendButtonEvent method called from button.cpp
-        //TODO: what if variable gets set from other task during this code? -> mutex around this code
-        switch (buttonCount) {
-            case 1: //define joystick center or freeze input
-                if (mode == controlMode_t::JOYSTICK){
-                    //joystick mode: calibrate joystick
-                    joystick_l->defineCenter();
-                } else if (mode == controlMode_t::MASSAGE){
-                    //massage mode: toggle freeze of input (lock joystick at current values)
-                    freezeInput = !freezeInput;
-                    if (freezeInput){
-                        buzzer->beep(5, 40, 25);
-                    } else {
-                        buzzer->beep(1, 300, 100);
-                    }
-                }
-                break;
-
-            case 12: //toggle alternative joystick mapping (reverse swapped) 
-                altStickMapping = !altStickMapping;
-                if (altStickMapping){
-                    buzzer->beep(6, 70, 50);
-                } else {
-                    buzzer->beep(1, 500, 100);
-                }
-                break;
-        }
-        //--- reset button event --- (only one action per run)
-        if (buttonCount > 0){
-            ESP_LOGI(TAG, "resetting button event/count");
-            buttonCount = 0;
-        }
-
-
-
-        //-----------------------
-        //------ slow loop ------
-        //-----------------------
-        //this section is run about every 5s (+500ms)
-        if (esp_log_timestamp() - timestamp_SlowLoopLastRun > 5000) {
-            ESP_LOGV(TAG, "running slow loop... time since last run: %.1fs", (float)(esp_log_timestamp() - timestamp_SlowLoopLastRun)/1000);
-            timestamp_SlowLoopLastRun = esp_log_timestamp();
-
-            //run function which detects timeout (switch to idle)
-            handleTimeout();
-        }
-
-    }//end while(1)
-}//end startHandleLoop
-
-
-
-//-----------------------------------
-//---------- resetTimeout -----------
-//-----------------------------------
-void controlledArmchair::resetTimeout(){
-    //TODO mutex
-    timestamp_lastActivity = esp_log_timestamp();
-}
-
-
-
-//------------------------------------
-//--------- sendButtonEvent ----------
-//------------------------------------
-void controlledArmchair::sendButtonEvent(uint8_t count){
-    //TODO mutex - if not replaced with queue
-    ESP_LOGI(TAG, "setting button event");
-    buttonCount = count;
-}
-
-
-
-//------------------------------------
-//---------- handleTimeout -----------
-//------------------------------------
-//percentage the duty can vary since last timeout check and still counts as incative 
-//TODO: add this to config
-float inactivityTolerance = 10; 
-
-//local function that checks whether two values differ more than a given tolerance
-bool validateActivity(float dutyOld, float dutyNow, float tolerance){
-    float dutyDelta = dutyNow - dutyOld;
-    if (fabs(dutyDelta) < tolerance) {
-        return false; //no significant activity detected
-    } else {
-        return true; //there was activity
-    }
-}
-
-//function that evaluates whether there is no activity/change on the motor duty for a certain time. If so, a switch to IDLE is issued. - has to be run repeatedly in a slow interval
-void controlledArmchair::handleTimeout(){
-    //check for timeout only when not idling already
-    if (mode != controlMode_t::IDLE) {
-        //get current duty from controlled motor objects
-        float dutyLeftNow = motorLeft->getStatus().duty;
-        float dutyRightNow = motorRight->getStatus().duty;
-
-        //activity detected on any of the two motors
-        if (validateActivity(dutyLeft_lastActivity, dutyLeftNow, inactivityTolerance) 
-                || validateActivity(dutyRight_lastActivity, dutyRightNow, inactivityTolerance)
-           ){
-            ESP_LOGD(TAG, "timeout check: [activity] detected since last check -> reset");
-            //reset last duty and timestamp
-            dutyLeft_lastActivity = dutyLeftNow;
-            dutyRight_lastActivity = dutyRightNow;
-            resetTimeout();
-        }
-        //no activity on any motor and msTimeout exceeded
-        else if (esp_log_timestamp() - timestamp_lastActivity > config.timeoutMs){
-            ESP_LOGI(TAG, "timeout check: [TIMEOUT], no activity for more than %.ds  -> switch to idle", config.timeoutMs/1000);
-            //toggle to idle mode
-            toggleIdle();
-        }
-        else {
-            ESP_LOGD(TAG, "timeout check: [inactive], last activity %.1f s ago, timeout after %d s", (float)(esp_log_timestamp() - timestamp_lastActivity)/1000, config.timeoutMs/1000);
-        }
-    }
-}
-
-
-
-//-----------------------------------
-//----------- changeMode ------------
-//-----------------------------------
-//function to change to a specified control mode
-void controlledArmchair::changeMode(controlMode_t modeNew) {
-    //reset timeout timer
-    resetTimeout();
-
-    //exit if target mode is already active
-    if (mode == modeNew) {
-        ESP_LOGE(TAG, "changeMode: Already in target mode '%s' -> nothing to change", controlModeStr[(int)mode]);
-        return;
-    }
-
-    //copy previous mode
-    modePrevious = mode;
-
-	ESP_LOGW(TAG, "=== changing mode from %s to %s ===", controlModeStr[(int)mode], controlModeStr[(int)modeNew]);
-
-	//========== commands change FROM mode ==========
-	//run functions when changing FROM certain mode
-	switch(modePrevious){
-		default:
-			ESP_LOGI(TAG, "noting to execute when changing FROM this mode");
-			break;
-
-#ifdef JOYSTICK_LOG_IN_IDLE
-		case controlMode_t::IDLE:
-			ESP_LOGI(TAG, "disabling debug output for 'evaluatedJoystick'");
-			esp_log_level_set("evaluatedJoystick", ESP_LOG_WARN); //FIXME: loglevel from config
-			break;
-#endif
-
-		case controlMode_t::HTTP:
-			ESP_LOGW(TAG, "switching from http mode -> disabling http and wifi");
-			//stop http server
-			ESP_LOGI(TAG, "disabling http server...");
-			http_stop_server();
-
-			//FIXME: make wifi function work here - currently starting wifi at startup (see notes main.cpp)
-            //stop wifi
-            //TODO: decide whether ap or client is currently used - which has to be disabled?
-            //ESP_LOGI(TAG, "deinit wifi...");
-            //wifi_deinit_client();
-            //wifi_deinit_ap();
-            ESP_LOGI(TAG, "done stopping http mode");
-            break;
-
-        case controlMode_t::MASSAGE:
-            ESP_LOGW(TAG, "switching from MASSAGE mode -> restoring fading, reset frozen input");
-            //TODO: fix issue when downfading was disabled before switching to massage mode - currently it gets enabled again here...
-            //enable downfading (set to default value)
-            motorLeft->setFade(fadeType_t::DECEL, true);
-            motorRight->setFade(fadeType_t::DECEL, true);
-            //set upfading to default value
-            motorLeft->setFade(fadeType_t::ACCEL, true);
-            motorRight->setFade(fadeType_t::ACCEL, true);
-            //reset frozen input state
-            freezeInput = false;
-            break;
-
-        case controlMode_t::AUTO:
-            ESP_LOGW(TAG, "switching from AUTO mode -> restoring fading to default");
-            //TODO: fix issue when downfading was disabled before switching to auto mode - currently it gets enabled again here...
-            //enable downfading (set to default value)
-            motorLeft->setFade(fadeType_t::DECEL, true);
-            motorRight->setFade(fadeType_t::DECEL, true);
-            //set upfading to default value
-            motorLeft->setFade(fadeType_t::ACCEL, true);
-            motorRight->setFade(fadeType_t::ACCEL, true);
-            break;
-    }
-
-
-    //========== commands change TO mode ==========
-    //run functions when changing TO certain mode
-    switch(modeNew){
-        default:
-            ESP_LOGI(TAG, "noting to execute when changing TO this mode");
-            break;
-
-		case controlMode_t::IDLE:
-			buzzer->beep(1, 1500, 0);
-#ifdef JOYSTICK_LOG_IN_IDLE
-			esp_log_level_set("evaluatedJoystick", ESP_LOG_DEBUG);
-#endif
-			break;
-
-        case controlMode_t::HTTP:
-            ESP_LOGW(TAG, "switching to http mode -> enabling http and wifi");
-            //start wifi
-            //TODO: decide wether ap or client should be started
-            ESP_LOGI(TAG, "init wifi...");
-
-            //FIXME: make wifi function work here - currently starting wifi at startup (see notes main.cpp)
-            //wifi_init_client();
-            //wifi_init_ap();
-
-            //wait for wifi
-            //ESP_LOGI(TAG, "waiting for wifi...");
-            //vTaskDelay(1000 / portTICK_PERIOD_MS);
-
-            //start http server
-            ESP_LOGI(TAG, "init http server...");
-            http_init_server();
-            ESP_LOGI(TAG, "done initializing http mode");
-            break;
-
-        case controlMode_t::MASSAGE:
-            ESP_LOGW(TAG, "switching to MASSAGE mode -> reducing fading");
-            uint32_t shake_msFadeAccel = 500; //TODO: move this to config
-
-            //disable downfading (max. deceleration)
-            motorLeft->setFade(fadeType_t::DECEL, false);
-            motorRight->setFade(fadeType_t::DECEL, false);
-            //reduce upfading (increase acceleration)
-            motorLeft->setFade(fadeType_t::ACCEL, shake_msFadeAccel);
-            motorRight->setFade(fadeType_t::ACCEL, shake_msFadeAccel);
-            break;
-
-    }
-
-    //--- update mode to new mode ---
-    //TODO: add mutex
-    mode = modeNew;
-}
-
-
-//TODO simplify the following 3 functions? can be replaced by one?
-
-//-----------------------------------
-//----------- toggleIdle ------------
-//-----------------------------------
-//function to toggle between IDLE and previous active mode
-void controlledArmchair::toggleIdle() {
-    //toggle between IDLE and previous mode
-    toggleMode(controlMode_t::IDLE);
-}
-
-
-
-//------------------------------------
-//----------- toggleModes ------------
-//------------------------------------
-//function to toggle between two modes, but prefer first argument if entirely different mode is currently active
-void controlledArmchair::toggleModes(controlMode_t modePrimary, controlMode_t modeSecondary) {
-    //switch to secondary mode when primary is already active
-    if (mode == modePrimary){
-        ESP_LOGW(TAG, "toggleModes: switching from primaryMode %s to secondarMode %s", controlModeStr[(int)mode], controlModeStr[(int)modeSecondary]);
-        buzzer->beep(2,200,100);
-        changeMode(modeSecondary); //switch to secondary mode
-    } 
-    //switch to primary mode when any other mode is active
-    else {
-        ESP_LOGW(TAG, "toggleModes: switching from %s to primary mode %s", controlModeStr[(int)mode], controlModeStr[(int)modePrimary]);
-        buzzer->beep(4,200,100);
-        changeMode(modePrimary);
-    }
-}
-
-
-
-//-----------------------------------
-//----------- toggleMode ------------
-//-----------------------------------
-//function that toggles between certain mode and previous mode
-void controlledArmchair::toggleMode(controlMode_t modePrimary){
-
-    //switch to previous mode when primary is already active
-    if (mode == modePrimary){
-        ESP_LOGW(TAG, "toggleMode: switching from primaryMode %s to previousMode %s", controlModeStr[(int)mode], controlModeStr[(int)modePrevious]);
-        //buzzer->beep(2,200,100);
-        changeMode(modePrevious); //switch to previous mode
-    } 
-    //switch to primary mode when any other mode is active
-    else {
-        ESP_LOGW(TAG, "toggleModes: switching from %s to primary mode %s", controlModeStr[(int)mode], controlModeStr[(int)modePrimary]);
-        //buzzer->beep(4,200,100);
-        changeMode(modePrimary);
-    }
-}
diff --git a/main/control.hpp b/main/control.hpp
deleted file mode 100644
index 8ed1e66..0000000
--- a/main/control.hpp
+++ /dev/null
@@ -1,130 +0,0 @@
-#pragma once
-
-#include "motordrivers.hpp"
-#include "motorctl.hpp"
-#include "buzzer.hpp"
-#include "http.hpp"
-#include "auto.hpp"
-
-
-//--------------------------------------------
-//---- struct, enum, variable declarations ---
-//--------------------------------------------
-//enum that decides how the motors get controlled
-enum class controlMode_t {IDLE, JOYSTICK, MASSAGE, HTTP, MQTT, BLUETOOTH, AUTO};
-//string array representing the mode enum (for printing the state as string)
-extern const char* controlModeStr[7];
-
-//--- control_config_t ---
-//struct with config parameters
-typedef struct control_config_t {
-    controlMode_t defaultMode;  //default mode after startup and toggling IDLE
-    //timeout options
-    uint32_t timeoutMs;         //time of inactivity after which the mode gets switched to IDLE
-    float timeoutTolerancePer;  //percentage the duty can vary between timeout checks considered still inactive
-} control_config_t;
-
-
-
-
-//==================================
-//========= control class ==========
-//==================================
-//controls the mode the armchair operates
-//repeatedly generates the motor commands corresponding to current mode and sends those to motorcontrol
-class controlledArmchair {
-    public:
-        //--- constructor ---
-        controlledArmchair (
-                control_config_t config_f,
-                buzzer_t* buzzer_f,
-                controlledMotor* motorLeft_f,
-                controlledMotor* motorRight_f,
-                evaluatedJoystick* joystick_f,
-                httpJoystick* httpJoystick_f
-                );
-
-        //--- functions ---
-        //task that repeatedly generates motor commands depending on the current mode
-        void startHandleLoop();
-
-        //function that changes to a specified control mode
-        void changeMode(controlMode_t modeNew);
-
-        //function that toggle between IDLE and previous active mode (or default if not switched to certain mode yet)
-        void toggleIdle();
-
-        //function that toggles between two modes, but prefers first argument if entirely different mode is currently active
-        void toggleModes(controlMode_t modePrimary, controlMode_t modeSecondary);
-
-        //toggle between certain mode and previous mode
-        void toggleMode(controlMode_t modePrimary);
-
-        //function that restarts timer which initiates the automatic timeout (switch to IDLE) after certain time of inactivity
-        void resetTimeout();
-
-        //function for sending a button event (e.g. from button task at event) to control task
-        //TODO: use queue instead?
-        void sendButtonEvent(uint8_t count);
-
-    private:
-
-        //--- functions ---
-        //function that evaluates whether there is no activity/change on the motor duty for a certain time, if so a switch to IDLE is issued. - has to be run repeatedly in a slow interval
-        void handleTimeout();
-
-        //--- objects ---
-        buzzer_t* buzzer;
-        controlledMotor* motorLeft;
-        controlledMotor* motorRight;
-        httpJoystick* httpJoystickMain_l;
-        evaluatedJoystick* joystick_l;
-
-        //---variables ---
-        //struct for motor commands returned by generate functions of each mode
-        motorCommands_t commands;
-        //struct with config parameters
-        control_config_t config;
-
-        //store joystick data
-        joystickData_t stickData;
-        bool altStickMapping; //alternative joystick mapping (reverse mapped differently)
-
-        //variables for http mode
-        uint32_t http_timestamp_lastData = 0;
-
-        //variables for MASSAGE mode
-        bool freezeInput = false;
-
-        //variables for AUTO mode
-        auto_instruction_t instruction = auto_instruction_t::NONE; //variable to receive instructions from automatedArmchair
-        
-        //variable to store button event
-        uint8_t buttonCount = 0;
-
-        //definition of mode enum
-        controlMode_t mode = controlMode_t::IDLE;
-
-        //variable to store mode when toggling IDLE mode 
-        controlMode_t modePrevious; //default mode
-
-        //command preset for idling motors
-        const motorCommand_t cmd_motorIdle = {
-            .state = motorstate_t::IDLE,
-            .duty = 0
-        };
-        const motorCommands_t cmds_bothMotorsIdle = {
-            .left = cmd_motorIdle,
-            .right = cmd_motorIdle
-        };
-
-        //variable for slow loop
-        uint32_t timestamp_SlowLoopLastRun = 0;
-
-        //variables for detecting timeout (switch to idle, after inactivity)
-        float dutyLeft_lastActivity = 0;
-        float dutyRight_lastActivity = 0;
-        uint32_t timestamp_lastActivity = 0;
-};
-
-
diff --git a/main/main.cpp b/main/main.cpp
deleted file mode 100644
index 05e7653..0000000
--- a/main/main.cpp
+++ /dev/null
@@ -1,299 +0,0 @@
-extern "C"
-{
-#include <stdio.h>
-#include <esp_system.h>
-#include <esp_event.h>
-#include <nvs_flash.h>
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "driver/gpio.h"
-#include "esp_log.h"
-#include "sdkconfig.h"
-#include "esp_spiffs.h"    
-
-#include "driver/ledc.h"
-
-//custom C files
-#include "wifi.h"
-}
-
-//custom C++ files
-#include "config.hpp"
-#include "control.hpp" 
-#include "button.hpp"
-#include "http.hpp"
-
-//tag for logging
-static const char * TAG = "main";
-
-
-
-//====================================
-//========== motorctl task ===========
-//====================================
-//task for handling the motors (ramp, current limit, driver)
-void task_motorctl( void * pvParameters ){
-    ESP_LOGI(TAG, "starting handle loop...");
-    while(1){
-        motorRight.handle();
-        motorLeft.handle();
-        //10khz -> T=100us
-        vTaskDelay(10 / portTICK_PERIOD_MS);
-    }
-}
-
-
-
-//======================================
-//============ buzzer task =============
-//======================================
-//TODO: move the task creation to buzzer class (buzzer.cpp)
-//e.g. only have function buzzer.createTask() in app_main
-void task_buzzer( void * pvParameters ){
-    ESP_LOGI("task_buzzer", "Start of buzzer task...");
-        //run function that waits for a beep events to arrive in the queue
-        //and processes them
-        buzzer.processQueue();
-}
-
-
-
-//=======================================
-//============ control task =============
-//=======================================
-//task that controls the armchair modes and initiates commands generation and applies them to driver
-void task_control( void * pvParameters ){
-    ESP_LOGI(TAG, "Initializing controlledArmchair and starting handle loop");
-    //start handle loop (control object declared in config.hpp)
-    control.startHandleLoop();
-}
-
-
-
-//======================================
-//============ button task =============
-//======================================
-//task that handles the button interface/commands
-void task_button( void * pvParameters ){
-    ESP_LOGI(TAG, "Initializing command-button and starting handle loop");
-    //create button instance
-    buttonCommands commandButton(&buttonJoystick, &joystick, &control, &buzzer, &motorLeft, &motorRight);
-    //start handle loop
-    commandButton.startHandleLoop();
-}
-
-
-
-//=======================================
-//============== fan task ===============
-//=======================================
-//task that controlls fans for cooling the drivers
-void task_fans( void * pvParameters ){
-    ESP_LOGI(TAG, "Initializing fans and starting fan handle loop");
-    //create fan instances with config defined in config.cpp
-    controlledFan fan(configCooling, &motorLeft, &motorRight);
-    //repeatedly run fan handle function in a slow loop
-    while(1){
-        fan.handle();
-        vTaskDelay(500 / portTICK_PERIOD_MS);
-    }
-}
-
-
-
-//=================================
-//========== init spiffs ==========
-//=================================
-//initialize spi flash filesystem (used for webserver)
-void init_spiffs(){
-    ESP_LOGI(TAG, "init spiffs");
-    esp_vfs_spiffs_conf_t esp_vfs_spiffs_conf = {
-        .base_path = "/spiffs",
-        .partition_label = NULL,
-        .max_files = 5,
-        .format_if_mount_failed = true};
-    esp_vfs_spiffs_register(&esp_vfs_spiffs_conf);
-
-    size_t total = 0;
-    size_t used = 0;
-    esp_spiffs_info(NULL, &total, &used);
-
-    ESP_LOGI(TAG, "SPIFFS: total %d, used %d", total, used);
-    esp_vfs_spiffs_unregister(NULL);
-}
-
-
-
-//==================================
-//======== define loglevels ========
-//==================================
-void setLoglevels(void){
-    //set loglevel for all tags:
-    esp_log_level_set("*", ESP_LOG_WARN);
-
-    //--- set loglevel for individual tags ---
-    esp_log_level_set("main", ESP_LOG_INFO);
-    esp_log_level_set("buzzer", ESP_LOG_ERROR);
-    //esp_log_level_set("motordriver", ESP_LOG_INFO);
-    //esp_log_level_set("motor-control", ESP_LOG_DEBUG);
-    //esp_log_level_set("evaluatedJoystick", ESP_LOG_DEBUG);
-    //esp_log_level_set("joystickCommands", ESP_LOG_DEBUG);
-    esp_log_level_set("button", ESP_LOG_INFO);
-    esp_log_level_set("control", ESP_LOG_INFO);
-    esp_log_level_set("fan-control", ESP_LOG_INFO);
-    esp_log_level_set("wifi", ESP_LOG_INFO);
-    esp_log_level_set("http", ESP_LOG_INFO);
-    esp_log_level_set("automatedArmchair", ESP_LOG_DEBUG);
-    //esp_log_level_set("current-sensors", ESP_LOG_INFO);
-}
-
-
-
-//=================================
-//=========== app_main ============
-//=================================
-extern "C" void app_main(void) {
-    //enable 5V volate regulator
-    gpio_pad_select_gpio(GPIO_NUM_17);                                                  
-    gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT);
-    gpio_set_level(GPIO_NUM_17, 1);                                                      
-
-    //---- define log levels ----
-	setLoglevels();
-    
-    //----------------------------------------------
-    //--- create task for controlling the motors ---
-    //----------------------------------------------
-    //task that receives commands, handles ramp and current limit and executes commands using the motordriver function
-    xTaskCreate(&task_motorctl, "task_motor-control", 2048, NULL, 6, NULL);
-
-    //------------------------------
-    //--- create task for buzzer ---
-    //------------------------------
-    xTaskCreate(&task_buzzer, "task_buzzer", 2048, NULL, 2, NULL);
-
-    //-------------------------------
-    //--- create task for control ---
-    //-------------------------------
-    //task that generates motor commands depending on the current mode and sends those to motorctl task
-    xTaskCreate(&task_control, "task_control", 4096, NULL, 5, NULL);
-
-    //------------------------------
-    //--- create task for button ---
-    //------------------------------
-    //task that evaluates and processes the button input and runs the configured commands
-    xTaskCreate(&task_button, "task_button", 4096, NULL, 4, NULL);
-
-    //-----------------------------------
-    //--- create task for fan control ---
-    //-----------------------------------
-    //task that evaluates and processes the button input and runs the configured commands
-    xTaskCreate(&task_fans, "task_fans", 2048, NULL, 1, NULL);
-
-
-    //beep at startup
-    buzzer.beep(3, 70, 50);
-
-    //--- initialize nvs-flash and netif (needed for wifi) ---
-    wifi_initNvs_initNetif();
-
-    //--- initialize spiffs ---
-    init_spiffs();
-
-    //--- initialize and start wifi ---
-    //FIXME: run wifi_init_client or wifi_init_ap as intended from control.cpp when switching state 
-    //currently commented out because of error "assert failed: xQueueSemaphoreTake queue.c:1549 (pxQueue->uxItemSize == 0)" when calling control->changeMode from button.cpp
-    //when calling control.changeMode(http) from main.cpp it worked without error for some reason?
-    ESP_LOGI(TAG,"starting wifi...");
-    //wifi_init_client(); //connect to existing wifi
-    wifi_init_ap(); //start access point
-    ESP_LOGI(TAG,"done starting wifi");
-
-
-    //--- testing http server ---
-    //    wifi_init_client(); //connect to existing wifi
-    //    vTaskDelay(2000 / portTICK_PERIOD_MS);
-    //    ESP_LOGI(TAG, "initializing http server");
-    //    http_init_server();
-    
-
-    //--- testing force http mode after startup ---
-        //control.changeMode(controlMode_t::HTTP);
-
-
-	//--- main loop ---
-	//does nothing except for testing things
-	while(1){
-		vTaskDelay(1000 / portTICK_PERIOD_MS);
-
-		//---------------------------------
-		//-------- TESTING section --------
-		//---------------------------------
-		// //--- test functions at mode change HTTP ---
-		// control.changeMode(controlMode_t::HTTP);
-		// vTaskDelay(10000 / portTICK_PERIOD_MS);
-		// control.changeMode(controlMode_t::IDLE);
-		// vTaskDelay(10000 / portTICK_PERIOD_MS);
-
-
-		//--- test wifi functions ---
-		// ESP_LOGI(TAG, "creating AP");
-		// wifi_init_ap(); //start accesspoint
-		// vTaskDelay(15000 / portTICK_PERIOD_MS);
-		// ESP_LOGI(TAG, "stopping wifi");
-		// wifi_deinit_ap();  //stop wifi access point
-		// vTaskDelay(5000 / portTICK_PERIOD_MS);
-		// ESP_LOGI(TAG, "connecting to wifi");
-		// wifi_init_client(); //connect to existing wifi
-		// vTaskDelay(10000 / portTICK_PERIOD_MS);
-		// ESP_LOGI(TAG, "stopping wifi");
-		// wifi_deinit_client(); //stop wifi client
-		// vTaskDelay(5000 / portTICK_PERIOD_MS);
-
-
-		//--- test button ---
-		//buttonJoystick.handle();
-		// if (buttonJoystick.risingEdge){
-		//     ESP_LOGI(TAG, "button pressed, was released for %d ms", buttonJoystick.msReleased);
-		//     buzzer.beep(2, 100, 50);
-
-		// }else if (buttonJoystick.fallingEdge){
-		//     ESP_LOGI(TAG, "button released, was pressed for %d ms", buttonJoystick.msPressed);
-		//     buzzer.beep(1, 200, 0);
-		// }
-
-
-		//--- test joystick commands ---
-		// motorCommands_t commands = joystick_generateCommandsDriving(joystick);
-		// motorRight.setTarget(commands.right.state, commands.right.duty); //TODO make motorctl.setTarget also accept motorcommand struct directly
-		// motorLeft.setTarget(commands.left.state, commands.left.duty); //TODO make motorctl.setTarget also accept motorcommand struct directly
-		// //motorRight.setTarget(commands.right.state, commands.right.duty);
-
-
-		//--- test joystick class ---
-		//joystickData_t data = joystick.getData();
-		//ESP_LOGI(TAG, "position=%s, x=%.1f%%, y=%.1f%%, radius=%.1f%%, angle=%.2f",
-		//        joystickPosStr[(int)data.position], data.x*100, data.y*100, data.radius*100, data.angle);
-
-		//--- test the motor driver ---
-		//fade up duty - forward
-		//   for (int duty=0; duty<=100; duty+=5) {
-		//       motorLeft.setTarget(motorstate_t::FWD, duty);
-		//       vTaskDelay(100 / portTICK_PERIOD_MS); 
-		//   }
-
-
-		//--- test controlledMotor --- (ramp)
-		// //brake for 1 s
-		// motorLeft.setTarget(motorstate_t::BRAKE);
-		// vTaskDelay(1000 / portTICK_PERIOD_MS);
-		// //command 90% - reverse
-		// motorLeft.setTarget(motorstate_t::REV, 90);
-		// vTaskDelay(5000 / portTICK_PERIOD_MS);
-		// //command 100% - forward
-		// motorLeft.setTarget(motorstate_t::FWD, 100);
-		// vTaskDelay(1000 / portTICK_PERIOD_MS);
-
-	}
-
-}
diff --git a/sdkconfig b/sdkconfig
deleted file mode 100644
index f7c6b17..0000000
--- a/sdkconfig
+++ /dev/null
@@ -1,1397 +0,0 @@
-#
-# Automatically generated file. DO NOT EDIT.
-# Espressif IoT Development Framework (ESP-IDF) Project Configuration
-#
-CONFIG_IDF_CMAKE=y
-CONFIG_IDF_TARGET_ARCH_XTENSA=y
-CONFIG_IDF_TARGET="esp32"
-CONFIG_IDF_TARGET_ESP32=y
-CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000
-
-#
-# SDK tool configuration
-#
-CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-"
-# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set
-# end of SDK tool configuration
-
-#
-# Build type
-#
-CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y
-# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set
-CONFIG_APP_BUILD_GENERATE_BINARIES=y
-CONFIG_APP_BUILD_BOOTLOADER=y
-CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y
-# end of Build type
-
-#
-# Application manager
-#
-CONFIG_APP_COMPILE_TIME_DATE=y
-# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set
-# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set
-# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set
-CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16
-# end of Application manager
-
-#
-# Bootloader config
-#
-CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000
-CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
-# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set
-# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set
-# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
-# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
-# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
-# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
-CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y
-# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
-# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
-CONFIG_BOOTLOADER_LOG_LEVEL=3
-# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set
-CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y
-# CONFIG_BOOTLOADER_FACTORY_RESET is not set
-# CONFIG_BOOTLOADER_APP_TEST is not set
-CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y
-CONFIG_BOOTLOADER_WDT_ENABLE=y
-# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set
-CONFIG_BOOTLOADER_WDT_TIME_MS=9000
-# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set
-# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set
-# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set
-# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set
-CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0
-# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set
-CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y
-# end of Bootloader config
-
-#
-# Security features
-#
-# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set
-# CONFIG_SECURE_BOOT is not set
-# CONFIG_SECURE_FLASH_ENC_ENABLED is not set
-# end of Security features
-
-#
-# Serial flasher config
-#
-CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200
-# CONFIG_ESPTOOLPY_NO_STUB is not set
-# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set
-# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set
-CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
-# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
-CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y
-CONFIG_ESPTOOLPY_FLASHMODE="dio"
-# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set
-CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
-# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
-# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
-CONFIG_ESPTOOLPY_FLASHFREQ="40m"
-# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
-# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
-CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
-# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
-# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
-# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
-# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
-# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
-CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
-CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
-CONFIG_ESPTOOLPY_BEFORE_RESET=y
-# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
-CONFIG_ESPTOOLPY_BEFORE="default_reset"
-CONFIG_ESPTOOLPY_AFTER_RESET=y
-# CONFIG_ESPTOOLPY_AFTER_NORESET is not set
-CONFIG_ESPTOOLPY_AFTER="hard_reset"
-# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set
-# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set
-# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set
-CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
-# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set
-# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set
-# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set
-# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set
-CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200
-CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
-# end of Serial flasher config
-
-#
-# Partition Table
-#
-# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
-# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set
-# CONFIG_PARTITION_TABLE_TWO_OTA is not set
-CONFIG_PARTITION_TABLE_CUSTOM=y
-CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
-CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
-CONFIG_PARTITION_TABLE_OFFSET=0x8000
-CONFIG_PARTITION_TABLE_MD5=y
-# end of Partition Table
-
-#
-# Compiler options
-#
-CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
-# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
-# CONFIG_COMPILER_OPTIMIZATION_PERF is not set
-# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
-CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
-# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
-# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
-CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2
-# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set
-CONFIG_COMPILER_HIDE_PATHS_MACROS=y
-# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
-# CONFIG_COMPILER_CXX_RTTI is not set
-CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
-# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
-# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
-# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set
-# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
-# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set
-# CONFIG_COMPILER_DUMP_RTL_FILES is not set
-# end of Compiler options
-
-#
-# Component config
-#
-
-#
-# Application Level Tracing
-#
-# CONFIG_APPTRACE_DEST_JTAG is not set
-CONFIG_APPTRACE_DEST_NONE=y
-CONFIG_APPTRACE_LOCK_ENABLE=y
-# end of Application Level Tracing
-
-#
-# ESP-ASIO
-#
-# CONFIG_ASIO_SSL_SUPPORT is not set
-# end of ESP-ASIO
-
-#
-# Bluetooth
-#
-# CONFIG_BT_ENABLED is not set
-# end of Bluetooth
-
-#
-# CoAP Configuration
-#
-CONFIG_COAP_MBEDTLS_PSK=y
-# CONFIG_COAP_MBEDTLS_PKI is not set
-# CONFIG_COAP_MBEDTLS_DEBUG is not set
-CONFIG_COAP_LOG_DEFAULT_LEVEL=0
-# end of CoAP Configuration
-
-#
-# Driver configurations
-#
-
-#
-# ADC configuration
-#
-# CONFIG_ADC_FORCE_XPD_FSM is not set
-CONFIG_ADC_DISABLE_DAC=y
-# end of ADC configuration
-
-#
-# MCPWM configuration
-#
-# CONFIG_MCPWM_ISR_IN_IRAM is not set
-# end of MCPWM configuration
-
-#
-# SPI configuration
-#
-# CONFIG_SPI_MASTER_IN_IRAM is not set
-CONFIG_SPI_MASTER_ISR_IN_IRAM=y
-# CONFIG_SPI_SLAVE_IN_IRAM is not set
-CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
-# end of SPI configuration
-
-#
-# TWAI configuration
-#
-# CONFIG_TWAI_ISR_IN_IRAM is not set
-# CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC is not set
-# CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST is not set
-# CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID is not set
-# CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set
-# end of TWAI configuration
-
-#
-# UART configuration
-#
-# CONFIG_UART_ISR_IN_IRAM is not set
-# end of UART configuration
-
-#
-# RTCIO configuration
-#
-# CONFIG_RTCIO_SUPPORT_RTC_GPIO_DESC is not set
-# end of RTCIO configuration
-
-#
-# GPIO Configuration
-#
-# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set
-# end of GPIO Configuration
-
-#
-# GDMA Configuration
-#
-# CONFIG_GDMA_CTRL_FUNC_IN_IRAM is not set
-# CONFIG_GDMA_ISR_IRAM_SAFE is not set
-# end of GDMA Configuration
-# end of Driver configurations
-
-#
-# eFuse Bit Manager
-#
-# CONFIG_EFUSE_CUSTOM_TABLE is not set
-# CONFIG_EFUSE_VIRTUAL is not set
-# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set
-CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y
-# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set
-CONFIG_EFUSE_MAX_BLK_LEN=192
-# end of eFuse Bit Manager
-
-#
-# ESP-TLS
-#
-CONFIG_ESP_TLS_USING_MBEDTLS=y
-# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set
-# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set
-# CONFIG_ESP_TLS_SERVER is not set
-# CONFIG_ESP_TLS_PSK_VERIFICATION is not set
-# CONFIG_ESP_TLS_INSECURE is not set
-# end of ESP-TLS
-
-#
-# ESP32-specific
-#
-CONFIG_ESP32_REV_MIN_0=y
-# CONFIG_ESP32_REV_MIN_1 is not set
-# CONFIG_ESP32_REV_MIN_2 is not set
-# CONFIG_ESP32_REV_MIN_3 is not set
-CONFIG_ESP32_REV_MIN=0
-CONFIG_ESP32_DPORT_WORKAROUND=y
-# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set
-CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y
-# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set
-CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160
-# CONFIG_ESP32_SPIRAM_SUPPORT is not set
-# CONFIG_ESP32_TRAX is not set
-CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0
-# CONFIG_ESP32_ULP_COPROC_ENABLED is not set
-CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0
-CONFIG_ESP32_DEBUG_OCDAWARE=y
-CONFIG_ESP32_BROWNOUT_DET=y
-CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y
-# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set
-# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set
-# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set
-# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set
-# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set
-# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set
-# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set
-CONFIG_ESP32_BROWNOUT_DET_LVL=0
-CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
-# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set
-# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set
-# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set
-CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y
-# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set
-# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set
-# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set
-CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024
-CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000
-CONFIG_ESP32_XTAL_FREQ_40=y
-# CONFIG_ESP32_XTAL_FREQ_26 is not set
-# CONFIG_ESP32_XTAL_FREQ_AUTO is not set
-CONFIG_ESP32_XTAL_FREQ=40
-# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set
-# CONFIG_ESP32_NO_BLOBS is not set
-# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
-# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set
-# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set
-CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5
-# end of ESP32-specific
-
-#
-# ADC-Calibration
-#
-CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y
-CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y
-CONFIG_ADC_CAL_LUT_ENABLE=y
-# end of ADC-Calibration
-
-#
-# Common ESP-related
-#
-CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
-# end of Common ESP-related
-
-#
-# Ethernet
-#
-CONFIG_ETH_ENABLED=y
-CONFIG_ETH_USE_ESP32_EMAC=y
-CONFIG_ETH_PHY_INTERFACE_RMII=y
-CONFIG_ETH_RMII_CLK_INPUT=y
-# CONFIG_ETH_RMII_CLK_OUTPUT is not set
-CONFIG_ETH_RMII_CLK_IN_GPIO=0
-CONFIG_ETH_DMA_BUFFER_SIZE=512
-CONFIG_ETH_DMA_RX_BUFFER_NUM=10
-CONFIG_ETH_DMA_TX_BUFFER_NUM=10
-CONFIG_ETH_USE_SPI_ETHERNET=y
-# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set
-# CONFIG_ETH_SPI_ETHERNET_W5500 is not set
-# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set
-# CONFIG_ETH_USE_OPENETH is not set
-# end of Ethernet
-
-#
-# Event Loop Library
-#
-# CONFIG_ESP_EVENT_LOOP_PROFILING is not set
-CONFIG_ESP_EVENT_POST_FROM_ISR=y
-CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y
-# end of Event Loop Library
-
-#
-# GDB Stub
-#
-# end of GDB Stub
-
-#
-# ESP HTTP client
-#
-CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
-# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set
-CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y
-# end of ESP HTTP client
-
-#
-# HTTP Server
-#
-CONFIG_HTTPD_MAX_REQ_HDR_LEN=512
-CONFIG_HTTPD_MAX_URI_LEN=512
-CONFIG_HTTPD_ERR_RESP_NO_DELAY=y
-CONFIG_HTTPD_PURGE_BUF_LEN=32
-# CONFIG_HTTPD_LOG_PURGE_DATA is not set
-CONFIG_HTTPD_WS_SUPPORT=y
-# end of HTTP Server
-
-#
-# ESP HTTPS OTA
-#
-# CONFIG_OTA_ALLOW_HTTP is not set
-# end of ESP HTTPS OTA
-
-#
-# ESP HTTPS server
-#
-# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set
-# end of ESP HTTPS server
-
-#
-# Hardware Settings
-#
-
-#
-# MAC Config
-#
-CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y
-CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y
-CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y
-CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y
-# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set
-CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y
-CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4
-# end of MAC Config
-
-#
-# Sleep Config
-#
-CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
-CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y
-# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set
-# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND is not set
-# end of Sleep Config
-
-#
-# RTC Clock Config
-#
-# end of RTC Clock Config
-# end of Hardware Settings
-
-#
-# IPC (Inter-Processor Call)
-#
-CONFIG_ESP_IPC_TASK_STACK_SIZE=1536
-CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
-CONFIG_ESP_IPC_ISR_ENABLE=y
-# end of IPC (Inter-Processor Call)
-
-#
-# LCD and Touch Panel
-#
-
-#
-# LCD Peripheral Configuration
-#
-CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32
-# end of LCD Peripheral Configuration
-# end of LCD and Touch Panel
-
-#
-# ESP NETIF Adapter
-#
-CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120
-CONFIG_ESP_NETIF_TCPIP_LWIP=y
-# CONFIG_ESP_NETIF_LOOPBACK is not set
-CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y
-# end of ESP NETIF Adapter
-
-#
-# PHY
-#
-CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y
-# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set
-CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20
-CONFIG_ESP_PHY_MAX_TX_POWER=20
-CONFIG_ESP_PHY_REDUCE_TX_POWER=y
-# end of PHY
-
-#
-# Power Management
-#
-# CONFIG_PM_ENABLE is not set
-# end of Power Management
-
-#
-# ESP Ringbuf
-#
-# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set
-# CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH is not set
-# end of ESP Ringbuf
-
-#
-# ESP System Settings
-#
-# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set
-CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
-# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set
-# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set
-# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set
-
-#
-# Memory protection
-#
-# end of Memory protection
-
-CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
-CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
-CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584
-CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y
-# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set
-# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set
-CONFIG_ESP_MAIN_TASK_AFFINITY=0x0
-CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048
-CONFIG_ESP_CONSOLE_UART_DEFAULT=y
-# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
-# CONFIG_ESP_CONSOLE_NONE is not set
-CONFIG_ESP_CONSOLE_UART=y
-CONFIG_ESP_CONSOLE_MULTIPLE_UART=y
-CONFIG_ESP_CONSOLE_UART_NUM=0
-CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200
-CONFIG_ESP_INT_WDT=y
-CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
-CONFIG_ESP_INT_WDT_CHECK_CPU1=y
-CONFIG_ESP_TASK_WDT=y
-# CONFIG_ESP_TASK_WDT_PANIC is not set
-CONFIG_ESP_TASK_WDT_TIMEOUT_S=5
-CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
-CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
-# CONFIG_ESP_PANIC_HANDLER_IRAM is not set
-# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set
-# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set
-CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y
-# end of ESP System Settings
-
-#
-# High resolution timer (esp_timer)
-#
-# CONFIG_ESP_TIMER_PROFILING is not set
-CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y
-CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y
-CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584
-CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1
-# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set
-# CONFIG_ESP_TIMER_IMPL_FRC2 is not set
-CONFIG_ESP_TIMER_IMPL_TG0_LAC=y
-# end of High resolution timer (esp_timer)
-
-#
-# Wi-Fi
-#
-CONFIG_ESP32_WIFI_ENABLED=y
-CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
-CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
-# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set
-CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y
-CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1
-CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32
-# CONFIG_ESP32_WIFI_CSI_ENABLED is not set
-CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
-CONFIG_ESP32_WIFI_TX_BA_WIN=6
-CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
-CONFIG_ESP32_WIFI_RX_BA_WIN=6
-CONFIG_ESP32_WIFI_NVS_ENABLED=y
-CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
-# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set
-CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
-CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
-CONFIG_ESP32_WIFI_IRAM_OPT=y
-CONFIG_ESP32_WIFI_RX_IRAM_OPT=y
-CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y
-# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set
-# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set
-# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set
-CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y
-# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set
-CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7
-# end of Wi-Fi
-
-#
-# Core dump
-#
-# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set
-# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set
-CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y
-# end of Core dump
-
-#
-# FAT Filesystem support
-#
-# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set
-CONFIG_FATFS_CODEPAGE_437=y
-# CONFIG_FATFS_CODEPAGE_720 is not set
-# CONFIG_FATFS_CODEPAGE_737 is not set
-# CONFIG_FATFS_CODEPAGE_771 is not set
-# CONFIG_FATFS_CODEPAGE_775 is not set
-# CONFIG_FATFS_CODEPAGE_850 is not set
-# CONFIG_FATFS_CODEPAGE_852 is not set
-# CONFIG_FATFS_CODEPAGE_855 is not set
-# CONFIG_FATFS_CODEPAGE_857 is not set
-# CONFIG_FATFS_CODEPAGE_860 is not set
-# CONFIG_FATFS_CODEPAGE_861 is not set
-# CONFIG_FATFS_CODEPAGE_862 is not set
-# CONFIG_FATFS_CODEPAGE_863 is not set
-# CONFIG_FATFS_CODEPAGE_864 is not set
-# CONFIG_FATFS_CODEPAGE_865 is not set
-# CONFIG_FATFS_CODEPAGE_866 is not set
-# CONFIG_FATFS_CODEPAGE_869 is not set
-# CONFIG_FATFS_CODEPAGE_932 is not set
-# CONFIG_FATFS_CODEPAGE_936 is not set
-# CONFIG_FATFS_CODEPAGE_949 is not set
-# CONFIG_FATFS_CODEPAGE_950 is not set
-CONFIG_FATFS_CODEPAGE=437
-CONFIG_FATFS_LFN_NONE=y
-# CONFIG_FATFS_LFN_HEAP is not set
-# CONFIG_FATFS_LFN_STACK is not set
-CONFIG_FATFS_FS_LOCK=0
-CONFIG_FATFS_TIMEOUT_MS=10000
-CONFIG_FATFS_PER_FILE_CACHE=y
-# CONFIG_FATFS_USE_FASTSEEK is not set
-# end of FAT Filesystem support
-
-#
-# Modbus configuration
-#
-CONFIG_FMB_COMM_MODE_TCP_EN=y
-CONFIG_FMB_TCP_PORT_DEFAULT=502
-CONFIG_FMB_TCP_PORT_MAX_CONN=5
-CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20
-CONFIG_FMB_COMM_MODE_RTU_EN=y
-CONFIG_FMB_COMM_MODE_ASCII_EN=y
-CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150
-CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
-CONFIG_FMB_QUEUE_LENGTH=20
-CONFIG_FMB_PORT_TASK_STACK_SIZE=4096
-CONFIG_FMB_SERIAL_BUF_SIZE=256
-CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8
-CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000
-CONFIG_FMB_PORT_TASK_PRIO=10
-# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set
-CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y
-# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set
-CONFIG_FMB_PORT_TASK_AFFINITY=0x0
-CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y
-CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233
-CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20
-CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20
-CONFIG_FMB_CONTROLLER_STACK_SIZE=4096
-CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20
-# CONFIG_FMB_TIMER_PORT_ENABLED is not set
-# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set
-# end of Modbus configuration
-
-#
-# FreeRTOS
-#
-# CONFIG_FREERTOS_UNICORE is not set
-CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF
-CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y
-CONFIG_FREERTOS_CORETIMER_0=y
-# CONFIG_FREERTOS_CORETIMER_1 is not set
-CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y
-CONFIG_FREERTOS_HZ=100
-CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
-# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
-# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
-CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
-# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
-CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
-CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
-CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y
-# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set
-# CONFIG_FREERTOS_ASSERT_DISABLE is not set
-CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
-CONFIG_FREERTOS_ISR_STACKSIZE=1536
-# CONFIG_FREERTOS_LEGACY_HOOKS is not set
-CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
-CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
-# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set
-CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1
-CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048
-CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10
-CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0
-# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
-# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
-CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y
-CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y
-# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
-# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set
-CONFIG_FREERTOS_DEBUG_OCDAWARE=y
-# CONFIG_FREERTOS_FPU_IN_ISR is not set
-CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y
-# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set
-# end of FreeRTOS
-
-#
-# Hardware Abstraction Layer (HAL) and Low Level (LL)
-#
-CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y
-# CONFIG_HAL_ASSERTION_DISABLE is not set
-# CONFIG_HAL_ASSERTION_SILIENT is not set
-# CONFIG_HAL_ASSERTION_ENABLE is not set
-CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2
-# end of Hardware Abstraction Layer (HAL) and Low Level (LL)
-
-#
-# Heap memory debugging
-#
-CONFIG_HEAP_POISONING_DISABLED=y
-# CONFIG_HEAP_POISONING_LIGHT is not set
-# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set
-CONFIG_HEAP_TRACING_OFF=y
-# CONFIG_HEAP_TRACING_STANDALONE is not set
-# CONFIG_HEAP_TRACING_TOHOST is not set
-# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set
-# end of Heap memory debugging
-
-#
-# jsmn
-#
-# CONFIG_JSMN_PARENT_LINKS is not set
-# CONFIG_JSMN_STRICT is not set
-# end of jsmn
-
-#
-# libsodium
-#
-# end of libsodium
-
-#
-# Log output
-#
-# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
-# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
-# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
-CONFIG_LOG_DEFAULT_LEVEL_INFO=y
-# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
-# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
-CONFIG_LOG_DEFAULT_LEVEL=3
-# CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT is not set
-# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set
-CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE=y
-CONFIG_LOG_MAXIMUM_LEVEL=5
-CONFIG_LOG_COLORS=y
-CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
-# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
-# end of Log output
-
-#
-# LWIP
-#
-CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
-# CONFIG_LWIP_NETIF_API is not set
-# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set
-CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
-# CONFIG_LWIP_L2_TO_L3_COPY is not set
-# CONFIG_LWIP_IRAM_OPTIMIZATION is not set
-CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
-# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set
-# CONFIG_LWIP_SO_LINGER is not set
-CONFIG_LWIP_SO_REUSE=y
-CONFIG_LWIP_SO_REUSE_RXTOALL=y
-# CONFIG_LWIP_SO_RCVBUF is not set
-# CONFIG_LWIP_NETBUF_RECVINFO is not set
-CONFIG_LWIP_IP4_FRAG=y
-CONFIG_LWIP_IP6_FRAG=y
-# CONFIG_LWIP_IP4_REASSEMBLY is not set
-# CONFIG_LWIP_IP6_REASSEMBLY is not set
-# CONFIG_LWIP_IP_FORWARD is not set
-# CONFIG_LWIP_STATS is not set
-# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set
-CONFIG_LWIP_ESP_GRATUITOUS_ARP=y
-CONFIG_LWIP_GARP_TMR_INTERVAL=60
-CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
-CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
-# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
-CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y
-# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set
-CONFIG_LWIP_DHCP_OPTIONS_LEN=68
-
-#
-# DHCP server
-#
-CONFIG_LWIP_DHCPS=y
-CONFIG_LWIP_DHCPS_LEASE_UNIT=60
-CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8
-# end of DHCP server
-
-# CONFIG_LWIP_AUTOIP is not set
-CONFIG_LWIP_IPV6=y
-# CONFIG_LWIP_IPV6_AUTOCONFIG is not set
-CONFIG_LWIP_IPV6_NUM_ADDRESSES=3
-# CONFIG_LWIP_IPV6_FORWARD is not set
-# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set
-CONFIG_LWIP_NETIF_LOOPBACK=y
-CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
-
-#
-# TCP
-#
-CONFIG_LWIP_MAX_ACTIVE_TCP=16
-CONFIG_LWIP_MAX_LISTENING_TCP=16
-CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y
-CONFIG_LWIP_TCP_MAXRTX=12
-CONFIG_LWIP_TCP_SYNMAXRTX=12
-CONFIG_LWIP_TCP_MSS=1440
-CONFIG_LWIP_TCP_TMR_INTERVAL=250
-CONFIG_LWIP_TCP_MSL=60000
-CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000
-CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744
-CONFIG_LWIP_TCP_WND_DEFAULT=5744
-CONFIG_LWIP_TCP_RECVMBOX_SIZE=6
-CONFIG_LWIP_TCP_QUEUE_OOSEQ=y
-# CONFIG_LWIP_TCP_SACK_OUT is not set
-# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set
-CONFIG_LWIP_TCP_OVERSIZE_MSS=y
-# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
-# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
-CONFIG_LWIP_TCP_RTO_TIME=1500
-# end of TCP
-
-#
-# UDP
-#
-CONFIG_LWIP_MAX_UDP_PCBS=16
-CONFIG_LWIP_UDP_RECVMBOX_SIZE=6
-# end of UDP
-
-#
-# Checksums
-#
-# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set
-# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set
-CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y
-# end of Checksums
-
-CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072
-CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
-# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set
-# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set
-CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF
-# CONFIG_LWIP_PPP_SUPPORT is not set
-CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3
-CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5
-# CONFIG_LWIP_SLIP_SUPPORT is not set
-
-#
-# ICMP
-#
-CONFIG_LWIP_ICMP=y
-# CONFIG_LWIP_MULTICAST_PING is not set
-# CONFIG_LWIP_BROADCAST_PING is not set
-# end of ICMP
-
-#
-# LWIP RAW API
-#
-CONFIG_LWIP_MAX_RAW_PCBS=16
-# end of LWIP RAW API
-
-#
-# SNTP
-#
-CONFIG_LWIP_SNTP_MAX_SERVERS=1
-# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set
-CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000
-# end of SNTP
-
-CONFIG_LWIP_ESP_LWIP_ASSERT=y
-
-#
-# Hooks
-#
-# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set
-CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y
-# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set
-CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y
-# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set
-# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set
-CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y
-# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set
-# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set
-CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y
-# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set
-# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set
-# end of Hooks
-
-# CONFIG_LWIP_DEBUG is not set
-# end of LWIP
-
-#
-# mbedTLS
-#
-CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
-# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
-# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
-CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
-CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
-CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
-# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set
-# CONFIG_MBEDTLS_DEBUG is not set
-
-#
-# mbedTLS v2.28.x related
-#
-# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set
-# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set
-# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set
-CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y
-# end of mbedTLS v2.28.x related
-
-#
-# Certificate Bundle
-#
-CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
-CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y
-# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set
-# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set
-# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set
-CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200
-# end of Certificate Bundle
-
-# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set
-# CONFIG_MBEDTLS_CMAC_C is not set
-CONFIG_MBEDTLS_HARDWARE_AES=y
-CONFIG_MBEDTLS_HARDWARE_MPI=y
-CONFIG_MBEDTLS_HARDWARE_SHA=y
-CONFIG_MBEDTLS_ROM_MD5=y
-# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set
-# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set
-CONFIG_MBEDTLS_HAVE_TIME=y
-# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
-CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y
-CONFIG_MBEDTLS_SHA512_C=y
-CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
-# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set
-# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set
-# CONFIG_MBEDTLS_TLS_DISABLED is not set
-CONFIG_MBEDTLS_TLS_SERVER=y
-CONFIG_MBEDTLS_TLS_CLIENT=y
-CONFIG_MBEDTLS_TLS_ENABLED=y
-
-#
-# TLS Key Exchange Methods
-#
-# CONFIG_MBEDTLS_PSK_MODES is not set
-CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y
-CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y
-CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y
-CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y
-CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y
-CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y
-CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y
-# end of TLS Key Exchange Methods
-
-CONFIG_MBEDTLS_SSL_RENEGOTIATION=y
-# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set
-CONFIG_MBEDTLS_SSL_PROTO_TLS1=y
-CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y
-CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y
-# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set
-# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set
-CONFIG_MBEDTLS_SSL_ALPN=y
-CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y
-CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y
-CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y
-CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y
-
-#
-# Symmetric Ciphers
-#
-CONFIG_MBEDTLS_AES_C=y
-# CONFIG_MBEDTLS_CAMELLIA_C is not set
-# CONFIG_MBEDTLS_DES_C is not set
-CONFIG_MBEDTLS_RC4_DISABLED=y
-# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set
-# CONFIG_MBEDTLS_RC4_ENABLED is not set
-# CONFIG_MBEDTLS_BLOWFISH_C is not set
-# CONFIG_MBEDTLS_XTEA_C is not set
-CONFIG_MBEDTLS_CCM_C=y
-CONFIG_MBEDTLS_GCM_C=y
-# CONFIG_MBEDTLS_NIST_KW_C is not set
-# end of Symmetric Ciphers
-
-# CONFIG_MBEDTLS_RIPEMD160_C is not set
-
-#
-# Certificates
-#
-CONFIG_MBEDTLS_PEM_PARSE_C=y
-CONFIG_MBEDTLS_PEM_WRITE_C=y
-CONFIG_MBEDTLS_X509_CRL_PARSE_C=y
-CONFIG_MBEDTLS_X509_CSR_PARSE_C=y
-# end of Certificates
-
-CONFIG_MBEDTLS_ECP_C=y
-CONFIG_MBEDTLS_ECDH_C=y
-CONFIG_MBEDTLS_ECDSA_C=y
-# CONFIG_MBEDTLS_ECJPAKE_C is not set
-CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y
-CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y
-CONFIG_MBEDTLS_ECP_NIST_OPTIM=y
-# CONFIG_MBEDTLS_POLY1305_C is not set
-# CONFIG_MBEDTLS_CHACHA20_C is not set
-# CONFIG_MBEDTLS_HKDF_C is not set
-# CONFIG_MBEDTLS_THREADING_C is not set
-# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set
-# CONFIG_MBEDTLS_SECURITY_RISKS is not set
-# end of mbedTLS
-
-#
-# mDNS
-#
-CONFIG_MDNS_MAX_SERVICES=10
-CONFIG_MDNS_TASK_PRIORITY=1
-CONFIG_MDNS_TASK_STACK_SIZE=4096
-# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set
-CONFIG_MDNS_TASK_AFFINITY_CPU0=y
-# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set
-CONFIG_MDNS_TASK_AFFINITY=0x0
-CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000
-# CONFIG_MDNS_STRICT_MODE is not set
-CONFIG_MDNS_TIMER_PERIOD_MS=100
-# CONFIG_MDNS_NETWORKING_SOCKET is not set
-CONFIG_MDNS_MULTIPLE_INSTANCE=y
-# end of mDNS
-
-#
-# ESP-MQTT Configurations
-#
-CONFIG_MQTT_PROTOCOL_311=y
-CONFIG_MQTT_TRANSPORT_SSL=y
-CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
-CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
-# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
-# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
-# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
-# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
-# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
-# CONFIG_MQTT_CUSTOM_OUTBOX is not set
-# end of ESP-MQTT Configurations
-
-#
-# Newlib
-#
-CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y
-# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set
-# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set
-# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set
-# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set
-CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y
-# CONFIG_NEWLIB_NANO_FORMAT is not set
-# end of Newlib
-
-#
-# NVS
-#
-# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
-# end of NVS
-
-#
-# OpenSSL
-#
-# CONFIG_OPENSSL_DEBUG is not set
-CONFIG_OPENSSL_ERROR_STACK=y
-# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set
-CONFIG_OPENSSL_ASSERT_EXIT=y
-# end of OpenSSL
-
-#
-# OpenThread
-#
-# CONFIG_OPENTHREAD_ENABLED is not set
-# end of OpenThread
-
-#
-# PThreads
-#
-CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5
-CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072
-CONFIG_PTHREAD_STACK_MIN=768
-CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y
-# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set
-# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set
-CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1
-CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread"
-# end of PThreads
-
-#
-# SPI Flash driver
-#
-# CONFIG_SPI_FLASH_VERIFY_WRITE is not set
-# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set
-CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y
-CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y
-# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set
-# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set
-# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set
-# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set
-# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set
-CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y
-CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20
-CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1
-CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192
-# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set
-# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set
-# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set
-
-#
-# Auto-detect flash chips
-#
-CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y
-CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y
-CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y
-CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y
-# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set
-# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set
-# end of Auto-detect flash chips
-
-CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y
-# end of SPI Flash driver
-
-#
-# SPIFFS Configuration
-#
-CONFIG_SPIFFS_MAX_PARTITIONS=3
-
-#
-# SPIFFS Cache Configuration
-#
-CONFIG_SPIFFS_CACHE=y
-CONFIG_SPIFFS_CACHE_WR=y
-# CONFIG_SPIFFS_CACHE_STATS is not set
-# end of SPIFFS Cache Configuration
-
-CONFIG_SPIFFS_PAGE_CHECK=y
-CONFIG_SPIFFS_GC_MAX_RUNS=10
-# CONFIG_SPIFFS_GC_STATS is not set
-CONFIG_SPIFFS_PAGE_SIZE=256
-CONFIG_SPIFFS_OBJ_NAME_LEN=32
-# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set
-CONFIG_SPIFFS_USE_MAGIC=y
-CONFIG_SPIFFS_USE_MAGIC_LENGTH=y
-CONFIG_SPIFFS_META_LENGTH=4
-CONFIG_SPIFFS_USE_MTIME=y
-
-#
-# Debug Configuration
-#
-# CONFIG_SPIFFS_DBG is not set
-# CONFIG_SPIFFS_API_DBG is not set
-# CONFIG_SPIFFS_GC_DBG is not set
-# CONFIG_SPIFFS_CACHE_DBG is not set
-# CONFIG_SPIFFS_CHECK_DBG is not set
-# CONFIG_SPIFFS_TEST_VISUALISATION is not set
-# end of Debug Configuration
-# end of SPIFFS Configuration
-
-#
-# TCP Transport
-#
-
-#
-# Websocket
-#
-CONFIG_WS_TRANSPORT=y
-CONFIG_WS_BUFFER_SIZE=1024
-# end of Websocket
-# end of TCP Transport
-
-#
-# Unity unit testing library
-#
-CONFIG_UNITY_ENABLE_FLOAT=y
-CONFIG_UNITY_ENABLE_DOUBLE=y
-# CONFIG_UNITY_ENABLE_64BIT is not set
-# CONFIG_UNITY_ENABLE_COLOR is not set
-CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
-# CONFIG_UNITY_ENABLE_FIXTURE is not set
-# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set
-# end of Unity unit testing library
-
-#
-# Virtual file system
-#
-CONFIG_VFS_SUPPORT_IO=y
-CONFIG_VFS_SUPPORT_DIR=y
-CONFIG_VFS_SUPPORT_SELECT=y
-CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
-CONFIG_VFS_SUPPORT_TERMIOS=y
-
-#
-# Host File System I/O (Semihosting)
-#
-CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1
-# end of Host File System I/O (Semihosting)
-# end of Virtual file system
-
-#
-# Wear Levelling
-#
-# CONFIG_WL_SECTOR_SIZE_512 is not set
-CONFIG_WL_SECTOR_SIZE_4096=y
-CONFIG_WL_SECTOR_SIZE=4096
-# end of Wear Levelling
-
-#
-# Wi-Fi Provisioning Manager
-#
-CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
-CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
-# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set
-# end of Wi-Fi Provisioning Manager
-
-#
-# Supplicant
-#
-CONFIG_WPA_MBEDTLS_CRYPTO=y
-# CONFIG_WPA_WAPI_PSK is not set
-# CONFIG_WPA_SUITE_B_192 is not set
-# CONFIG_WPA_DEBUG_PRINT is not set
-# CONFIG_WPA_TESTING_OPTIONS is not set
-# CONFIG_WPA_WPS_STRICT is not set
-# CONFIG_WPA_11KV_SUPPORT is not set
-# CONFIG_WPA_MBO_SUPPORT is not set
-# CONFIG_WPA_DPP_SUPPORT is not set
-# end of Supplicant
-# end of Component config
-
-#
-# Compatibility options
-#
-# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set
-# end of Compatibility options
-
-# Deprecated options for backward compatibility
-CONFIG_TOOLPREFIX="xtensa-esp32-elf-"
-# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set
-# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
-# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set
-CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
-# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
-# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
-CONFIG_LOG_BOOTLOADER_LEVEL=3
-# CONFIG_APP_ROLLBACK_ENABLE is not set
-# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
-# CONFIG_FLASHMODE_QIO is not set
-# CONFIG_FLASHMODE_QOUT is not set
-CONFIG_FLASHMODE_DIO=y
-# CONFIG_FLASHMODE_DOUT is not set
-# CONFIG_MONITOR_BAUD_9600B is not set
-# CONFIG_MONITOR_BAUD_57600B is not set
-CONFIG_MONITOR_BAUD_115200B=y
-# CONFIG_MONITOR_BAUD_230400B is not set
-# CONFIG_MONITOR_BAUD_921600B is not set
-# CONFIG_MONITOR_BAUD_2MB is not set
-# CONFIG_MONITOR_BAUD_OTHER is not set
-CONFIG_MONITOR_BAUD_OTHER_VAL=115200
-CONFIG_MONITOR_BAUD=115200
-CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y
-# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
-CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
-# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
-# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
-CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2
-# CONFIG_CXX_EXCEPTIONS is not set
-CONFIG_STACK_CHECK_NONE=y
-# CONFIG_STACK_CHECK_NORM is not set
-# CONFIG_STACK_CHECK_STRONG is not set
-# CONFIG_STACK_CHECK_ALL is not set
-# CONFIG_WARN_WRITE_STRINGS is not set
-# CONFIG_DISABLE_GCC8_WARNINGS is not set
-# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
-CONFIG_ESP32_APPTRACE_DEST_NONE=y
-CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
-CONFIG_ADC2_DISABLE_DAC=y
-# CONFIG_SPIRAM_SUPPORT is not set
-CONFIG_TRACEMEM_RESERVE_DRAM=0x0
-# CONFIG_ULP_COPROC_ENABLED is not set
-CONFIG_ULP_COPROC_RESERVE_MEM=0
-CONFIG_BROWNOUT_DET=y
-CONFIG_BROWNOUT_DET_LVL_SEL_0=y
-# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set
-# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set
-# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set
-# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set
-# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set
-# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set
-# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set
-CONFIG_BROWNOUT_DET_LVL=0
-CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
-# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set
-# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set
-# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set
-# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set
-# CONFIG_NO_BLOBS is not set
-# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
-# CONFIG_EVENT_LOOP_PROFILING is not set
-CONFIG_POST_EVENTS_FROM_ISR=y
-CONFIG_POST_EVENTS_FROM_IRAM_ISR=y
-# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set
-CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y
-CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4
-CONFIG_ESP_SYSTEM_PD_FLASH=y
-# CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND is not set
-CONFIG_IPC_TASK_STACK_SIZE=1536
-CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y
-# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set
-CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
-CONFIG_ESP32_PHY_MAX_TX_POWER=20
-CONFIG_ESP32_REDUCE_PHY_TX_POWER=y
-# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set
-CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y
-# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set
-# CONFIG_ESP32S2_PANIC_GDBSTUB is not set
-CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
-CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
-CONFIG_MAIN_TASK_STACK_SIZE=3584
-CONFIG_CONSOLE_UART_DEFAULT=y
-# CONFIG_CONSOLE_UART_CUSTOM is not set
-# CONFIG_ESP_CONSOLE_UART_NONE is not set
-CONFIG_CONSOLE_UART=y
-CONFIG_CONSOLE_UART_NUM=0
-CONFIG_CONSOLE_UART_BAUDRATE=115200
-CONFIG_INT_WDT=y
-CONFIG_INT_WDT_TIMEOUT_MS=300
-CONFIG_INT_WDT_CHECK_CPU1=y
-CONFIG_TASK_WDT=y
-# CONFIG_TASK_WDT_PANIC is not set
-CONFIG_TASK_WDT_TIMEOUT_S=5
-CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
-CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
-# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set
-CONFIG_TIMER_TASK_STACK_SIZE=3584
-# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set
-# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
-CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
-CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150
-CONFIG_MB_MASTER_DELAY_MS_CONVERT=200
-CONFIG_MB_QUEUE_LENGTH=20
-CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096
-CONFIG_MB_SERIAL_BUF_SIZE=256
-CONFIG_MB_SERIAL_TASK_PRIO=10
-CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y
-CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233
-CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20
-CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20
-CONFIG_MB_CONTROLLER_STACK_SIZE=4096
-CONFIG_MB_EVENT_QUEUE_TIMEOUT=20
-# CONFIG_MB_TIMER_PORT_ENABLED is not set
-# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set
-CONFIG_TIMER_TASK_PRIORITY=1
-CONFIG_TIMER_TASK_STACK_DEPTH=2048
-CONFIG_TIMER_QUEUE_LENGTH=10
-# CONFIG_L2_TO_L3_COPY is not set
-# CONFIG_USE_ONLY_LWIP_SELECT is not set
-CONFIG_ESP_GRATUITOUS_ARP=y
-CONFIG_GARP_TMR_INTERVAL=60
-CONFIG_TCPIP_RECVMBOX_SIZE=32
-CONFIG_TCP_MAXRTX=12
-CONFIG_TCP_SYNMAXRTX=12
-CONFIG_TCP_MSS=1440
-CONFIG_TCP_MSL=60000
-CONFIG_TCP_SND_BUF_DEFAULT=5744
-CONFIG_TCP_WND_DEFAULT=5744
-CONFIG_TCP_RECVMBOX_SIZE=6
-CONFIG_TCP_QUEUE_OOSEQ=y
-# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set
-CONFIG_TCP_OVERSIZE_MSS=y
-# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set
-# CONFIG_TCP_OVERSIZE_DISABLE is not set
-CONFIG_UDP_RECVMBOX_SIZE=6
-CONFIG_TCPIP_TASK_STACK_SIZE=3072
-CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
-# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set
-# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set
-CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF
-# CONFIG_PPP_SUPPORT is not set
-CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5
-CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072
-CONFIG_ESP32_PTHREAD_STACK_MIN=768
-CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y
-# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set
-# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set
-CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1
-CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
-CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
-# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
-# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
-CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
-CONFIG_SUPPORT_TERMIOS=y
-CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1
-# End of deprecated options