Create 'control.hpp/cpp', Create 'button.hpp/cpp'
Add control.hpp and control.cpp - task that repeatedly generates motor commands depending on the current mode - function to change to a specified control mode Add button.hpp and button.cpp - class which runs commands depending on the count a button was pressed Update main.cpp - create button task - create control task - comment out previous testing code - remove unnecessary includes (already included in config.hpp) Add control.cpp and button.cpp to CMakeLists Notes: Tested this state on the armchair: All currently implemented features work. You can switch between IDLE and JOYSTICK by pressing the button 2 or 3 times. Also driving works well (limited to 60% duty, with no fans yet).
This commit is contained in:
parent
06451b47d0
commit
adb517c7ed
@ -1,2 +1,2 @@
|
||||
idf_component_register(SRCS "main.cpp" "motordrivers.cpp" "motorctl.cpp" "config.cpp" "joystick.cpp" "buzzer.cpp"
|
||||
idf_component_register(SRCS "main.cpp" "motordrivers.cpp" "motorctl.cpp" "config.cpp" "joystick.cpp" "buzzer.cpp" "control.cpp" "button.cpp"
|
||||
INCLUDE_DIRS ".")
|
||||
|
114
main/button.cpp
Normal file
114
main/button.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
extern "C"
|
||||
{
|
||||
#include <stdio.h>
|
||||
#include <esp_system.h>
|
||||
#include <esp_event.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_log.h"
|
||||
}
|
||||
|
||||
#include "control.hpp"
|
||||
#include "button.hpp"
|
||||
|
||||
|
||||
|
||||
//tag for logging
|
||||
static const char * TAG = "button";
|
||||
|
||||
|
||||
|
||||
//-----------------------------
|
||||
//-------- constructor --------
|
||||
//-----------------------------
|
||||
buttonCommands::buttonCommands(gpio_evaluatedSwitch * button_f, buzzer_t * buzzer_f ){
|
||||
//copy object pointers
|
||||
button = button_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){
|
||||
switch (count){
|
||||
//no such command
|
||||
default:
|
||||
ESP_LOGE(TAG, "no command for count=%d defined", count);
|
||||
buzzer->beep(3, 400, 100);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ESP_LOGW(TAG, "running command for count 1");
|
||||
buzzer->beep(1,500,1);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ESP_LOGW(TAG, "cmd %d: switching to IDLE", count);
|
||||
control_changeMode(controlMode_t::IDLE);
|
||||
buzzer->beep(1,1000,1);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
ESP_LOGW(TAG, "cmd %d: switching to JOYSTICK", count);
|
||||
control_changeMode(controlMode_t::JOYSTICK);
|
||||
buzzer->beep(2,400,100);
|
||||
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, 60, 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, 60, 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
|
||||
//run action function with current count of button presses
|
||||
ESP_LOGI(TAG, "timeout - running action function for count=%d", count);
|
||||
action(count);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
40
main/button.hpp
Normal file
40
main/button.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "gpio_evaluateSwitch.hpp"
|
||||
#include "buzzer.hpp"
|
||||
|
||||
|
||||
|
||||
//===================================
|
||||
//====== buttonCommands class =======
|
||||
//===================================
|
||||
//class which runs commands depending on the count a button was pressed
|
||||
class buttonCommands {
|
||||
public:
|
||||
//--- constructor ---
|
||||
buttonCommands (
|
||||
gpio_evaluatedSwitch * button_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);
|
||||
|
||||
//--- objects ---
|
||||
gpio_evaluatedSwitch* button;
|
||||
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;
|
||||
|
||||
};
|
||||
|
72
main/control.cpp
Normal file
72
main/control.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
extern "C"
|
||||
{
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_log.h"
|
||||
}
|
||||
|
||||
#include "motordrivers.hpp"
|
||||
#include "motorctl.hpp"
|
||||
#include "joystick.hpp"
|
||||
#include "config.hpp"
|
||||
#include "control.hpp"
|
||||
|
||||
|
||||
//=================================
|
||||
//===== variable declaration ======
|
||||
//=================================
|
||||
//tag for logging
|
||||
static const char * TAG = "control";
|
||||
|
||||
//definition of mode enum
|
||||
controlMode_t mode = controlMode_t::IDLE;
|
||||
const char* controlModeStr[6] = {"IDLE", "JOYSTICK", "MASSAGE", "MQTT", "BLUETOOTH", "AUTO"};
|
||||
|
||||
|
||||
|
||||
//==================================
|
||||
//========== handle task ===========
|
||||
//==================================
|
||||
//task that repeatedly generates motor commands depending on the current mode
|
||||
void task_control ( void * pvParameters ) {
|
||||
while (1){
|
||||
vTaskDelay(20 / portTICK_PERIOD_MS);
|
||||
|
||||
ESP_LOGV(TAG, "control task executing... mode=%s", controlModeStr[(int)mode]);
|
||||
|
||||
switch(mode) {
|
||||
default:
|
||||
mode = controlMode_t::IDLE;
|
||||
break;
|
||||
|
||||
case controlMode_t::IDLE:
|
||||
motorRight.setTarget(motorstate_t::IDLE, 0);
|
||||
motorLeft.setTarget(motorstate_t::IDLE, 0);
|
||||
break;
|
||||
|
||||
case controlMode_t::JOYSTICK:
|
||||
motorCommands_t commands = joystick_generateCommandsDriving(joystick);
|
||||
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;
|
||||
|
||||
//TODO: add other modes here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===================================
|
||||
//=========== changeMode ============
|
||||
//===================================
|
||||
//function to change to a specified control mode
|
||||
void control_changeMode(controlMode_t modeNew) {
|
||||
ESP_LOGW(TAG, "changing mode from %s to %s", controlModeStr[(int)mode], controlModeStr[(int)modeNew]);
|
||||
mode = modeNew;
|
||||
//TODO: add mutex
|
||||
}
|
||||
|
||||
|
||||
|
15
main/control.hpp
Normal file
15
main/control.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
//enum that decides how the motors get controlled
|
||||
enum class controlMode_t {IDLE, JOYSTICK, MASSAGE, MQTT, BLUETOOTH, AUTO};
|
||||
//extern controlMode_t mode;
|
||||
|
||||
//task that repeatedly generates motor commands depending on the current mode
|
||||
void task_control(void * pvParameters);
|
||||
|
||||
//function that changes to a specified control mode
|
||||
void control_changeMode(controlMode_t modeNew);
|
||||
|
||||
|
||||
|
@ -15,6 +15,8 @@ extern "C"
|
||||
}
|
||||
|
||||
#include "config.hpp"
|
||||
#include "control.hpp"
|
||||
#include "button.hpp"
|
||||
|
||||
//tag for logging
|
||||
static const char * TAG = "main";
|
||||
@ -31,7 +33,7 @@ void task_motorctl( void * pvParameters ){
|
||||
motorRight.handle();
|
||||
motorLeft.handle();
|
||||
//10khz -> T=100us
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
vTaskDelay(20 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +53,19 @@ void task_buzzer( void * pvParameters ){
|
||||
|
||||
|
||||
|
||||
//======================================
|
||||
//============ button task =============
|
||||
//======================================
|
||||
void task_button( void * pvParameters ){
|
||||
ESP_LOGI(TAG, "Initializing command-button and starting handle loop");
|
||||
//create button instance
|
||||
buttonCommands commandButton(&buttonJoystick, &buzzer);
|
||||
//start handle loop
|
||||
commandButton.startHandleLoop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================================
|
||||
//=========== app_main ============
|
||||
//=================================
|
||||
@ -61,22 +76,26 @@ extern "C" void app_main(void) {
|
||||
gpio_set_level(GPIO_NUM_17, 1);
|
||||
|
||||
|
||||
|
||||
//-------------------------------
|
||||
//---------- log level ----------
|
||||
//-------------------------------
|
||||
//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("motordriver", ESP_LOG_DEBUG);
|
||||
//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);
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
//--- 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, 5, NULL);
|
||||
|
||||
//------------------------------
|
||||
@ -84,33 +103,46 @@ extern "C" void app_main(void) {
|
||||
//------------------------------
|
||||
xTaskCreate(&task_buzzer, "task_buzzer", 2048, NULL, 5, NULL);
|
||||
|
||||
//-------------------------------
|
||||
//--- create task for control ---
|
||||
//-------------------------------
|
||||
//task that generates motor commands depending on the current mode and sends those to motorctl task (task_control is defined in control.cpp)
|
||||
xTaskCreate(&task_control, "task_control", 2048, NULL, 5, NULL);
|
||||
|
||||
//------------------------------
|
||||
//--- create task for button ---
|
||||
//------------------------------
|
||||
//task that evaluates and processes the button input and runs the configured commands
|
||||
xTaskCreate(&task_button, "task_buzzer", 2048, NULL, 5, NULL);
|
||||
|
||||
|
||||
//beep at startup
|
||||
buzzer.beep(3, 70, 50);
|
||||
|
||||
|
||||
while(1){
|
||||
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
|
||||
buttonJoystick.handle();
|
||||
|
||||
//--- testing button ---
|
||||
if (buttonJoystick.risingEdge){
|
||||
ESP_LOGI(TAG, "button pressed, was released for %d ms", buttonJoystick.msReleased);
|
||||
buzzer.beep(2, 100, 50);
|
||||
//--- testing 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);
|
||||
}
|
||||
// }else if (buttonJoystick.fallingEdge){
|
||||
// ESP_LOGI(TAG, "button released, was pressed for %d ms", buttonJoystick.msPressed);
|
||||
// buzzer.beep(1, 200, 0);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
//--- testing 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);
|
||||
// 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);
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user