jonny_jr9 a1bb808b62 Rework/simplify chairAdjust - now using a class
- complete rework of chairAdjust.cpp/.hpp
  created a class cControlledRest which is more readable
  and saves a lot of duplicate code

- joystick.cpp: move chair control via joystick to
  chairAdjust.cpp (prevents dependency loop)
- button.cpp: fix bug instant idle when changing to ADJUST_CHAIR

Note: briefly tested this state on a breakout board:
Mode change and call of new class methods works.
2024-02-11 23:22:33 +01:00

183 lines
6.8 KiB
C++

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(500 / portTICK_PERIOD_MS);
//esp_restart();
//-> 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
return;
}
//note: disabled joystick calibration due to accidential trigger
//
// 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){
ESP_LOGW(TAG, "cmd %d: toggle ADJUST_CHAIR", count);
control->toggleMode(controlMode_t::ADJUST_CHAIR);
}
//toggle idle when 2x pressed
else {
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);
decelEnabled = motorLeft->toggleFade(fadeType_t::ACCEL);
motorRight->toggleFade(fadeType_t::ACCEL);
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;
}
}
}