Add MANUAL mode, Add vfd direction support

vfd: extend vfd_setState function with direction enum (default fwd)
main: reduce log output from buzzer task
config: use mos1 as vfd_FWD output
control:
    add MANUAL state: motor can be controlled via preset buttons
    adjust code slightly to support new state (also see updated
    function-diagram)
This commit is contained in:
jonny_ji7
2022-08-19 16:29:59 +02:00
parent f6b2093650
commit dddd54b03a
9 changed files with 94 additions and 35 deletions

View File

@@ -10,13 +10,13 @@ extern "C" {
//===== define output gpio pins =====
//===================================
//4x stepper mosfet outputs for VFD
#define GPIO_VFD_FWD GPIO_NUM_4
#define GPIO_VFD_D0 GPIO_NUM_16
#define GPIO_VFD_D1 GPIO_NUM_2
#define GPIO_VFD_D2 GPIO_NUM_15
#define GPIO_VFD_FWD GPIO_NUM_4 //ST4
#define GPIO_VFD_D0 GPIO_NUM_16 //ST3
#define GPIO_VFD_D1 GPIO_NUM_2 //ST2
#define GPIO_VFD_D2 GPIO_NUM_15 //ST1
#define GPIO_MOS1 GPIO_NUM_18
#define GPIO_MOS2 GPIO_NUM_5
#define GPIO_VFD_REV GPIO_NUM_18 //mos1
#define GPIO_MOS2 GPIO_NUM_5 //mos2
#define GPIO_RELAY GPIO_NUM_13
#define GPIO_BUZZER GPIO_NUM_12

View File

@@ -79,7 +79,7 @@ int readAdc(adc1_channel_t adc_channel, bool inverted = false) {
//====================
static const char *TAG = "control";
const char* systemStateStr[4] = {"COUNTING", "WINDING_START", "WINDING", "TARGET_REACHED"};
const char* systemStateStr[5] = {"COUNTING", "WINDING_START", "WINDING", "TARGET_REACHED", "MANUAL"};
systemState_t controlState = COUNTING;
max7219_t display; //display device
@@ -117,6 +117,29 @@ void changeState (systemState_t stateNew) {
}
//===== check Stop Condition =====
//function that checks whether start button is released or target is reached (used in multiple states)
//returns true when stopped, false when no action
bool checkStopCondition(){
//--- stop conditions ---
//stop conditions that are checked in any mode
//disable motor and switch to COUNTING when start button released
if (SW_START.state == false) { //TODO use fallingEdge here more clean?
changeState(COUNTING);
vfd_setState(false);
return true;
}
//disable motor and switch to TARGET_REACHED
else if (lengthDiff >= 0 ) {
//TODO: display "REACHED" on 7segment here or reached state (start pressed but reached)
changeState(TARGET_REACHED);
vfd_setState(false);
return true;
} else {
return false;
}
}
//========================
//===== control task =====
@@ -207,6 +230,10 @@ void task_control(void *pvParameter)
lengthNow = 0;
buzzer.beep(1, 700, 100);
}
//TODO add preset switches
@@ -216,29 +243,22 @@ void task_control(void *pvParameter)
//calculate length difference
lengthDiff = lengthNow - lengthTarget;
//--- stop conditions ---
//stop conditions that are checked in any mode
//disable motor and switch to COUNTING when start button released
if (SW_START.state == false) { //TODO use fallingEdge here more clean?
changeState(COUNTING);
vfd_setState(false);
}
//disable motor and switch to TARGET_REACHED
else if (lengthDiff >= 0 ) {
//TODO: display "REACHED" on 7segment here or reached state (start pressed but reached)
changeState(TARGET_REACHED);
vfd_setState(false);
}
//--- statemachine ---
switch (controlState) {
case COUNTING: //no motor action
//TODO stop motor here every run instead of at button event?
vfd_setState(false);
//--- start winding to length ---
if (SW_START.risingEdge) {
changeState(WINDING_START);
vfd_setSpeedLevel(2); //start at low speed
vfd_setState(true); //start motor
timestamp_motorStarted = esp_log_timestamp(); //save time started
}
//--- switch to manual motor control (2 buttons + poti) ---
else if ( SW_PRESET2.state && (SW_PRESET1.state || SW_PRESET3.state) ) {
changeState(MANUAL);
buzzer.beep(4, 100, 60);
}
break;
@@ -247,6 +267,7 @@ void task_control(void *pvParameter)
if (esp_log_timestamp() - timestamp_motorStarted > 2000) {
changeState(WINDING);
}
checkStopCondition();
//TESTING: SIMULATE LENGTH INCREASE
//lengthNow += 2;
break;
@@ -279,6 +300,7 @@ void task_control(void *pvParameter)
//TESTING: SIMULATE LENGTH INCREASE
//lengthNow += 200;
}
checkStopCondition();
//see "stop conditions" above that switches to TARGET_REACHED when targed reached
break;
@@ -286,6 +308,23 @@ void task_control(void *pvParameter)
//nothing to do here yet
//see "stop conditions" above that switches to COUNTING when start button released
break;
case MANUAL:
//P2 + P1 -> turn left
if ( SW_PRESET2.state && SW_PRESET1.state && !SW_PRESET3.state ) {
vfd_setSpeedLevel(2); //TODO: use poti input for level
vfd_setState(true, REV);
}
//P2 + P3 -> turn right
else if ( SW_PRESET2.state && SW_PRESET2.state && !SW_PRESET1.state ) {
vfd_setSpeedLevel(2); //TODO: use poti input for level
vfd_setState(true, FWD);
}
else { //no switch combination matches anymore
vfd_setState(false);
changeState(COUNTING);
buzzer.beep(1, 1000, 100);
}
}

View File

@@ -22,8 +22,8 @@ extern "C"
typedef enum systemState_t {COUNTING, WINDING_START, WINDING, TARGET_REACHED} systemState_t;
extern const char* systemStateStr[4];
typedef enum systemState_t {COUNTING, WINDING_START, WINDING, TARGET_REACHED, MANUAL} systemState_t;
extern const char* systemStateStr[5];
void task_control(void *pvParameter);

View File

@@ -32,7 +32,7 @@ void init_gpios(){
gpio_configure_output(GPIO_VFD_D1);
gpio_configure_output(GPIO_VFD_D2);
//2x power mosfets
gpio_configure_output(GPIO_MOS1);
gpio_configure_output(GPIO_VFD_REV);
gpio_configure_output(GPIO_MOS2);
//onboard relay and buzzer
gpio_configure_output(GPIO_RELAY);
@@ -77,6 +77,7 @@ extern "C" void app_main()
//define loglevel
esp_log_level_set("*", ESP_LOG_INFO);
esp_log_level_set("buzzer", ESP_LOG_ERROR);
esp_log_level_set("control", ESP_LOG_INFO);
//create task for controlling the machine

View File

@@ -2,33 +2,48 @@
#define CHECK_BIT(var,pos) (((var)>>(pos)) & 1)
const char* vfd_directionStr[2] = {"FWD", "REV"};
static const char *TAG = "vfd";
uint8_t level = 0; //current speed level
bool state = false; //current state
vfd_direction_t direction = FWD; //current direction
//=============================
//========= setState ==========
//=============================
void vfd_setState(bool stateNew){
//only proceed and send log output when state is actually changed
if (state == stateNew) {
//already at target state -> nothing todo
void vfd_setState(bool stateNew, vfd_direction_t directionNew){
//only proceed and send log output when state or direction actually changed
if ( state == stateNew && direction == directionNew ) {
//already at target state and target direction -> do nothing
return;
}
//log old and new state
ESP_LOGI(TAG, "CHANGING vfd state from: %i %s", (int)state, vfd_directionStr[(int)direction]);
ESP_LOGI(TAG, "CHANGING vfd state to: %i %s", (int)stateNew, vfd_directionStr[(int)directionNew]);
//update stored state
state = stateNew;
direction = directionNew;
//turn motor on/off
//turn motor on/off with target direction
if (state == true) {
gpio_set_level(GPIO_VFD_FWD, 1);
switch (direction) {
case FWD:
gpio_set_level(GPIO_VFD_REV, 0);
gpio_set_level(GPIO_VFD_FWD, 1);
break;
case REV:
gpio_set_level(GPIO_VFD_FWD, 0);
gpio_set_level(GPIO_VFD_REV, 1);
break;
}
gpio_set_level(GPIO_RELAY, 1);
} else {
gpio_set_level(GPIO_VFD_FWD, 0);
gpio_set_level(GPIO_VFD_REV, 0);
gpio_set_level(GPIO_RELAY, 0);
}
ESP_LOGI(TAG, "CHANGED state to %i", (int)state);
}

View File

@@ -11,9 +11,13 @@ extern "C"
#include "config.hpp"
//enum defining motor direction
typedef enum vfd_direction_t {FWD, REV} vfd_direction_t;
//strubg array to be able to log direction state as string
extern const char* vfd_directionStr[2];
//function for setting the state (motor on/off)
void vfd_setState(bool stateNew);
//function for setting the state and optional direction of the motor: on/off, FWD/REV (default FWD)
void vfd_setState(bool stateNew, vfd_direction_t direction = FWD);
//function for setting the speed level (1-7)
void vfd_setSpeedLevel(uint8_t levelNew = 0);